From nobody@FreeBSD.org  Mon Dec  3 15:38:31 2012
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52])
	by hub.freebsd.org (Postfix) with ESMTP id EBE1179C
	for <freebsd-gnats-submit@FreeBSD.org>; Mon,  3 Dec 2012 15:38:30 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22])
	by mx1.freebsd.org (Postfix) with ESMTP id CF6178FC12
	for <freebsd-gnats-submit@FreeBSD.org>; Mon,  3 Dec 2012 15:38:30 +0000 (UTC)
Received: from red.freebsd.org (localhost [127.0.0.1])
	by red.freebsd.org (8.14.5/8.14.5) with ESMTP id qB3FcUh5000780
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 3 Dec 2012 15:38:30 GMT
	(envelope-from nobody@red.freebsd.org)
Received: (from nobody@localhost)
	by red.freebsd.org (8.14.5/8.14.5/Submit) id qB3FcUop000779;
	Mon, 3 Dec 2012 15:38:30 GMT
	(envelope-from nobody)
Message-Id: <201212031538.qB3FcUop000779@red.freebsd.org>
Date: Mon, 3 Dec 2012 15:38:30 GMT
From: Keith Arner <vornum@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: Problems with ephemeral port selection
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         174087
>Category:       kern
>Synopsis:       [tcp] Problems with ephemeral port selection
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    andre
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Dec 03 15:40:00 UTC 2012
>Closed-Date:    
>Last-Modified:  Wed Dec 12 15:30:00 UTC 2012
>Originator:     Keith Arner
>Release:        7.2
>Organization:
Panasas
>Environment:
FreeBSD pa-twin-19a 7.2-RELEASE FreeBSD 7.2-RELEASE #0: Mon Apr 19 16:24:09 EDT 2010     root@perf-x3:/usr/obj/usr0/jimz/freebsd-c-rack/sys/PANASAS  amd64
>Description:
Date:      Fri, 30 Nov 2012 09:09:08 -0500
From:      Keith Arner <vornum@gmail.com>
To:        freebsd-net@freebsd.org
Subject:   Problems with ephemeral port selection
Message-ID:  <CAEo_tUH9LPzPFP-O=317rYEQ3nT66b4biQshV_8=L8hReO_BLg@mail.gmail.com>

I've noticed some issues with ephemeral port number selection from
tcp_connect(), which limit the number of concurrent, outgoing connections
that can be established (connect(), rather than accept()).  Sifting through
the source code, I believe the issuess stem from two problems in the
tcp_connect() code path.  Specifically:

 1) The wrong function gets called to determine if a given ephemeral
    port number is currently usable.
 2) The ephemeral port number gets selected without considering the
    foreign addr/port.

Curiously, the effect of #1 mostly cancels the effect of #2, such that
the common calling convention gives you a correct result so long as you
only have a small number of outgoing connections.  However, once you get to
a large number of outgoing connections, things start to break down.  (I'll
define large and small later.)

As a side note, I have been working with FreeBSD 7.2.  The implementations
of several of the relevant functions have been refactored somewhere between
7.2-RELEASE and 9-STABLE, but the core problems in the logic seem to be
the same between versions.

For problem #1, the code path that selects the ephemeral port number is:
 tcp_connect() ->
   in_pcbbind() ->
     in_pcbbind_setup() ->
       in_pcb_lport() [not in FreeBSD 7.2] ->
         in_pcblookup_local()

There is a loop in in_pcb_lport() [or directly in in_pcbbind_setup() in
earlier releases] that considers candidate ephemeral port numbers and
calls in_pcblookup_local() to determine if a given candidate is suitable.
The default behaviour (if the caller has not set either SO_REUSEADDR or
SO_REUSEPORT) is to pick a local port number that is not in use by
*any* local TCP socket.

So long as the number of concurrent, outgoing connections is less than the
range configured by `sysctl net.inet.ip.portrange.*`, selecting a totally
unique ephemeral port number works OK.  However, you cannot exceed that
limit, even if each outgoing connection has a unique faddr/fport.  This
does not limit the number of connections that can be accept()'ed, only the
number of connections that can be connect()'ed.

In this particular path, I think the code should call in_pcblookup_hash(),
rather than in_pcblookup_local().  The criteria in in_pcblookup_hash() only
match if the full 5-tuple matches, rather than just the local port number.
The complication, of course, comes from the fact that in_pcbbind() is
called from both bind() and for the implicit bind that happens for a
connect().  The matching criteria in in_pcblookup_local() make sense for
the former but not quite for the later.

I mentioned that the above is the default behaviour you get when you don't
specify SO_REUSEADDR or SO_REUSEPORT.  Setting SO_REUSEADDR
before calling connect() has some surprizing consequences (surprizing in the
sense that I don't believe SO_REUSEADDR is supposed to have any effect
on connect()).  In this case, when in_pcblookup_local() is called, wild_okay
is set to false.  This changes the matching criteria to (in effect) allow
tcp_connect() to use the full 5-tuple space.  However, this brings us to the
second problem.

Problem #2 is that the ephemeral port number is chosen before the
fport/faddr gets set on the pcb; that is tcp_connect() calls in_pcbbind() to
select the ephemeral port number, *then* calls in_pcbconnect_setup() to
populate the fport/faddr.  With SO_REUSEADDR, in_pcbbind() can select
an in-use local port.  If the local port is used by a socket with a different
laddr/fport/faddr, all is good.  However, if the local port selection
results in a
full conflict it will get rejected by the call to in_pcblookup_hash() inside
in_pcbconnect_setup().  This happens *after* the loop inside
in_pcbbind(), so the call to tcp_connect() fails with EADDRINUSE.  Thus,
with SO_REUSEADDR, connect() can fail with EADDRINUSE long before
the ephemeral port space has been exhausted.  The application could re-try
the call to connect() and likely succeed, as a new local port would be
selected.

Overall, this behaviour hinders the ability to open a large number of
outbound connections:
 * If you don't specify SO_REUSEADDR, you have a fairly limited maximum
   number of outbound connections.
 * If you do specify SO_REUSEADDR, you are able to open a much larger
   number of outbound connections, but must retry on EADDRINUSE.

I believe that the logic under tcp_connect() should be modified to:

 - behave uniformly whether or not SO_REUSEADDR has been set
 - allow outgoing connection requests to re-use a local port number, so
   long as the remaining elements of the tuple (laddr, fport, faddr) are
   unique


==========
Follow-up from the freebsd-net mailing list:

Date:      Sat, 01 Dec 2012 11:31:31 -0300
From:      Fernando Gont <fernando@gont.com.ar>
To:        Keith Arner <vornum@gmail.com>
Cc:        freebsd-net@freebsd.org
Subject:   Re: Problems with ephemeral port selection
Message-ID:  <50BA14C3.4070601@gont.com.ar>
In-Reply-To: <CAEo_tUH9LPzPFP-O=317rYEQ3nT66b4biQshV_8=L8hReO_BLg@mail.gmail.com>
References:  <CAEo_tUH9LPzPFP-O=317rYEQ3nT66b4biQshV_8=L8hReO_BLg@mail.gmail.com>

Next in thread | Previous in thread | Raw E-Mail | Index | Archive | Help

Hi, Keith,

On 11/30/2012 11:09 AM, Keith Arner wrote:
>
>  - behave uniformly whether or not SO_REUSEADDR has been set
>  - allow outgoing connection requests to re-use a local port number, so
>    long as the remaining elements of the tuple (laddr, fport, faddr) are
>    unique

Please take a look at the discussion on how to "steal" incomming
connections in Section 3.1 of RFC 6056.

Cheers,
-- 
Fernando Gont
e-mail: fernando@gont.com.ar || fgont@si6networks.com
PGP Fingerprint: 7809 84F5 322E 45C7 F1C9 3945 96EE A9EF D076 FFF1

>How-To-Repeat:
connect() a large number of sockets, specifying SO_REUSEADDR before
calling connect().  Note that the call to connect() fails with
EADDRINUSE long before we run into any resource exhaustion.

Then connect() a large number of sockets, without specificying
SO_REUSADDR (while all the previous sockets are still open).  Note
that connect() then fails with EADDRNOTAVAIL;  this occurs as soon
as the total number of outgoing connections equals the ephemeral
port range.



#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <arpa/inet.h>

int last_child = -1;

#define complain(exit_val)                      \
    {                                           \
        return(exit_val);                       \
    }

int SockOpt(int s, int level, int opt)
{
    int opt_val = 1;
    int ret = setsockopt(s, level, opt, &opt_val, sizeof(opt_val));
    if (ret) {
        perror("Could not setsockopt() on socket");
        complain(-1);
    }
    return 0;
}


int open_server(int port)
{
    int ret;
    struct sockaddr_in sin;

    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = htonl(INADDR_ANY);
    sin.sin_port = htons(port);


    int server = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (server < 0) {
        perror("Could not open server socket");
        complain(-1);
    }

    SockOpt(server, SOL_SOCKET, SO_REUSEADDR);

    ret = bind(server, (struct sockaddr *)&sin, sizeof(sin));
    if (ret) {
        perror("Could not bind() server socket");
        complain(-1);
    }

    ret = listen(server, 5);
    if (ret) {
        perror("Could not listen() server socket");
        complain(-1);
    }

    return server;
}

int cycle_client(int server, int iteration, int port, int reuse)
{
    int ret;
    struct sockaddr_in sin;

    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    sin.sin_port = htons(port);

    int client = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (client < 0) {
        fprintf(stderr, "Iteration %d, errno %d: ", iteration, errno);
        perror("Could not open client socket");
        complain(-1);
    }

    if (reuse) {
        SockOpt(client, SOL_SOCKET, SO_REUSEADDR);
    }

    ret = connect(client, (struct sockaddr *)&sin, sizeof(sin));
    if (ret) {
        fprintf(stderr, "Iteration %d, errno %d: ", iteration, errno);
        perror("Could not connect() client socket");
        complain(-1);
    }

    int len;
    int child = accept(server, (struct sockaddr *)&sin, &len);
    if (child < 0) {
        fprintf(stderr, "Iteration %d, errno %d: ", iteration, errno);
        perror("Could not accept() child socket");
        complain(-1);
    }

    /* Why are we not closing the sockets?
     *
     * The point of this program is to illustrate the behaviour of the
     *  network stack when we open (or, rather connect()) a large number of
     *  outgoing sockets.  Thus, we want the sockets to linger around, to
     *  consume ephemeral port numbers.  Note that we could get largely
     *  similar behaviour by closing the sockets (if we close the client
     *  socket first), as the pcbs would linger in the TIME_WAIT state,
     *  consuming emphemeral port numbers.  
     *
     * Note that because TIME_WAIT connections count against up, the
     *  behaviour being illustrated does not rely on a large number of
     *  concurrent connections, just a large number of outgoing connections
     *  established over a short time period.  But it is easier to understand
     *  the operation of this program if we leave the sockets open.
    /* 
    ret = close(client);
    if (ret) {
        fprintf(stderr, "Iteration %d, errno %d: ", iteration), errno;
        perror("Could not close() client");
        complain(-1);
    }
    */

    /*
    if (last_child) {
        ret = close(child);
        if (ret) {
            fprintf(stderr, "Iteration %d, errno %d: ", iteration, errno);
            perror("Could not close() child");
            complain(-1);
        }
    }
    */

    last_child = child;

    return 0;
}

/* Main loop to illustrate ephemeral port number behaviour.*/
int main(int argc, void **argv)
{
    /* num_iterations: How many sockets do we want to try to open per remote
     *  port number?  Should be set higher than the number of unique
     *  ephemeral port numbers that the stack can choose from.  With the
     *  default FreeBSD settings, that works out to:
     *
     *  net.inet.ip.portrange.last: 65535
     *  net.inet.ip.portrange.first: 49152
     *
     *  65535 - 49152 = 16383
     */
    int num_iterations = 20 * 1000;

    /* num_ports: How many distinct remote ports to we want to connect to? */
    int num_ports = 2;

    /* port: base, remote port number to connect to */
    int port = 12345;

    /* reuse: Should we set SO_REUSEADDR before calling connect()?
     *  Note that we alternate this value each for each remote port, to
     *  illustrate the differences in behaviour between setting it or not. */
    int reuse = 1;

    int port_loop;

    for (port_loop=0; port_loop<num_ports; port_loop++) {
        /* Set up a listening socket on the next remote port number. */
        int server = open_server(port);

        int i=0;
        for(; i<num_iterations; i++) {
            /* Open a bunch of sockets; and bail out on the first failure. */
            if (cycle_client(server, i, port, reuse)) {
                break;
            }
        }
        /* How many connections did we manage to establish on this port
         *  number (and with this "reuse" setting)?  If all is working,
         *  we ought to be able to establish as many connections as there
         *  are ephemeral ports, and we ought to be able to do so for each
         *  remote port number (baring memory exhaustion problems). */
        fprintf(stderr, "port %d; reuse %d; opened %d\n",
               port, reuse, i);

        /* Advance to the next remote port, and toggle whether we set
         *  SO_REUSEADDR. */
        port++;
        reuse = !reuse;
    }
    return 0;
}

>Fix:


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-net 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Sun Dec 9 17:56:08 UTC 2012 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=174087 
Responsible-Changed-From-To: freebsd-net->andre 
Responsible-Changed-By: andre 
Responsible-Changed-When: Tue Dec 11 22:01:32 UTC 2012 
Responsible-Changed-Why:  
Looking into it. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=174087 

From: "Arner, Keith" <karner@panasas.com>
To: "bug-followup@FreeBSD.org" <bug-followup@FreeBSD.org>,
        "vornum@gmail.com"
	<vornum@gmail.com>
Cc:  
Subject: Re: kern/174087: [tcp] Problems with ephemeral port selection
Date: Wed, 12 Dec 2012 15:29:09 +0000

 --_002_CCEE0CF314A51karnerpanasascom_
 Content-Type: text/plain; charset="us-ascii"
 Content-ID: <1B8CE96098BACB49B16E9EE3997C4E41@panasas.com>
 Content-Transfer-Encoding: quoted-printable
 
 
 Here is a preliminary patch that I've developed against the
 7.2 release.
 
 The majority of this diff is refactoring theport selection
 loop out of in_pcbbind_setup() and into in_pcb_lport().  This
 portion of the patch I largely lifted from the 9.0 release.
 This version of in_pcb_lport() does not have the #ifdefs
 for INET or INET6 as I did not want to get too distracted
 by those details on a first pass.
 
 The meat of the change can be summarized as follows:
 
  1) tcp_connect() no longer calls in_pcbbind() explicitly;
     rather local port allocation is deferred to be done
     from in_pcbbonnect_setup().
  2) Within in_pcbconnect_setup() the call to in_pcbbind_setup()
     is changed to in_pcb_lport().  I could have left the call
     to in_pcbbind_setup(), but
     A) doing so would have meant a messy change to the function
        signature of in_pcbbind_setup(), and
     B) this particular call to in_pcbbind_setup() was being
        done *only* for local port allocation, so the bulk of
        the function body was being skipped anyway
  3) in_pcb_lport() is augmented to take the fport/faddr to
     check for uniqueness, and also an "ephemeral" argument
     to determine whether to take fport/faddr into account.
 
 With this change, I'm able to allocate the full available
 ephemeral port range both with and without SO_REUSEADDR,
 and without needing to retry on EADDRINUSE.  I can now open
 sockets until I exhaust memory/buffer space, rather than
 running into ephemeral port allocation problems.
 
 One important thing to note about this change is that it
 does *not* take into account the presence of sockets
 listening on a port number in the ephemeral port space
 (see the advice about port stealing in section 3.1 of
 RFC 6056).  Prior to this patch, the logic would avoid
 listening sockets as it would avoid any re-use of a
 local port number.
 
 Keith
 
 
 --_002_CCEE0CF314A51karnerpanasascom_
 Content-Type: application/octet-stream; name="mytmp"
 Content-Description: mytmp
 Content-Disposition: attachment; filename="mytmp"; size=10255;
 	creation-date="Wed, 12 Dec 2012 15:29:09 GMT";
 	modification-date="Wed, 12 Dec 2012 15:29:09 GMT"
 Content-ID: <37CF3ED48638F84EA9669CEE10777EBD@panasas.com>
 Content-Transfer-Encoding: base64
 
 Cj09PT0gLy9kZXBvdC9icmFuY2gvcGlvbmVlci1rYXJuZXItZDEvc3JjL2ZyZWVic2QtYy9zeXMv
 bmV0aW5ldC9pbl9wY2IuYyMyICh0ZXh0KSA9PT09CgpAQCAtMjU1LDEwICsyNTUsMTI3IEBACiAJ
 aWYgKGFub25wb3J0KQogCQlpbnAtPmlucF9mbGFncyB8PSBJTlBfQU5PTlBPUlQ7CiAJcmV0dXJu
 ICgwKTsKIH0KIAoraW50Citpbl9wY2JfbHBvcnQoc3RydWN0IGlucGNiICppbnAsCisJICAgICBz
 dHJ1Y3QgaW5fYWRkciAqZmFkZHJwLCB1X3Nob3J0ICpmcG9ydHAsCisJICAgICBzdHJ1Y3QgaW5f
 YWRkciAqbGFkZHJwLCB1X3Nob3J0ICpscG9ydHAsCisJICAgICBzdHJ1Y3QgdWNyZWQgKmNyZWQs
 IGludCB3aWxkLCBpbnQgZXBoZW1lcmFsKQoreworICAgICAgICBzdHJ1Y3QgaW5wY2JpbmZvICpw
 Y2JpbmZvOworICAgICAgICBzdHJ1Y3QgaW5wY2IgKnRtcGlucDsKKyAgICAgICAgdW5zaWduZWQg
 c2hvcnQgKmxhc3Rwb3J0OworICAgICAgICBpbnQgY291bnQsIGRvcmFuZG9tLCBlcnJvcjsKKyAg
 ICAgICAgdV9zaG9ydCBhdXgsIGZpcnN0LCBsYXN0LCBscG9ydDsKKyAgICAgICAgc3RydWN0IGlu
 X2FkZHIgbGFkZHI7CisKKyAgICAgICAgcGNiaW5mbyA9IGlucC0+aW5wX3BjYmluZm87CisKKyAg
 ICAgICAgLyoKKyAgICAgICAgICogQmVjYXVzZSBubyBhY3R1YWwgc3RhdGUgY2hhbmdlcyBvY2N1
 ciBoZXJlLCBhIGdsb2JhbCB3cml0ZSBsb2NrIG9uCisgICAgICAgICAqIHRoZSBwY2JpbmZvIGlz
 bid0IHJlcXVpcmVkLgorICAgICAgICAgKi8KKyAgICAgICAgSU5QX0lORk9fTE9DS19BU1NFUlQo
 cGNiaW5mbyk7CisgICAgICAgIElOUF9MT0NLX0FTU0VSVChpbnApOworCisgICAgICAgIGlmIChp
 bnAtPmlucF9mbGFncyAmIElOUF9ISUdIUE9SVCkgeworICAgICAgICAgICAgICAgIGZpcnN0ID0g
 aXBwb3J0X2hpZmlyc3RhdXRvOyAgIC8qIHN5c2N0bCAqLworICAgICAgICAgICAgICAgIGxhc3Qg
 ID0gaXBwb3J0X2hpbGFzdGF1dG87CisgICAgICAgICAgICAgICAgbGFzdHBvcnQgPSAmcGNiaW5m
 by0+aXBpX2xhc3RoaTsKKyAgICAgICAgfSBlbHNlIGlmIChpbnAtPmlucF9mbGFncyAmIElOUF9M
 T1dQT1JUKSB7CisgICAgICAgICAgICAgICAgZXJyb3IgPSBwcml2X2NoZWNrX2NyZWQoY3JlZCwg
 UFJJVl9ORVRJTkVUX1JFU0VSVkVEUE9SVCwgMCk7CisgICAgICAgICAgICAgICAgaWYgKGVycm9y
 KQorICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChlcnJvcik7CisgICAgICAgICAgICAg
 ICAgZmlyc3QgPSBpcHBvcnRfbG93Zmlyc3RhdXRvOyAgLyogMTAyMyAqLworICAgICAgICAgICAg
 ICAgIGxhc3QgID0gaXBwb3J0X2xvd2xhc3RhdXRvOyAgIC8qIDYwMCAqLworICAgICAgICAgICAg
 ICAgIGxhc3Rwb3J0ID0gJnBjYmluZm8tPmlwaV9sYXN0bG93OworICAgICAgICB9IGVsc2Ugewor
 ICAgICAgICAgICAgICAgIGZpcnN0ID0gaXBwb3J0X2ZpcnN0YXV0bzsgICAgIC8qIHN5c2N0bCAq
 LworICAgICAgICAgICAgICAgIGxhc3QgID0gaXBwb3J0X2xhc3RhdXRvOworICAgICAgICAgICAg
 ICAgIGxhc3Rwb3J0ID0gJnBjYmluZm8tPmlwaV9sYXN0cG9ydDsKKyAgICAgICAgfQorICAgICAg
 ICAvKgorICAgICAgICAgKiBGb3IgVURQLCB1c2UgcmFuZG9tIHBvcnQgYWxsb2NhdGlvbiBhcyBs
 b25nIGFzIHRoZSB1c2VyCisgICAgICAgICAqIGFsbG93cyBpdC4gIEZvciBUQ1AgKGFuZCBhcyBv
 ZiB5ZXQgdW5rbm93bikgY29ubmVjdGlvbnMsCisgICAgICAgICAqIHVzZSByYW5kb20gcG9ydCBh
 bGxvY2F0aW9uIG9ubHkgaWYgdGhlIHVzZXIgYWxsb3dzIGl0IEFORAorICAgICAgICAgKiBpcHBv
 cnRfdGljaygpIGFsbG93cyBpdC4KKyAgICAgICAgICovCisgICAgICAgIGlmIChpcHBvcnRfcmFu
 ZG9taXplZCAmJgorICAgICAgICAgICAgICAgICghaXBwb3J0X3N0b3ByYW5kb20gfHwgcGNiaW5m
 byA9PSAmdWRiaW5mbykpCisgICAgICAgICAgICAgICAgZG9yYW5kb20gPSAxOworICAgICAgICBl
 bHNlCisgICAgICAgICAgICAgICAgZG9yYW5kb20gPSAwOworICAgICAgICAvKgorICAgICAgICAg
 KiBJdCBtYWtlcyBubyBzZW5zZSB0byBkbyByYW5kb20gcG9ydCBhbGxvY2F0aW9uIGlmCisgICAg
 ICAgICAqIHdlIGhhdmUgdGhlIG9ubHkgcG9ydCBhdmFpbGFibGUuCisgICAgICAgICAqLworICAg
 ICAgICBpZiAoZmlyc3QgPT0gbGFzdCkKKyAgICAgICAgICAgICAgICBkb3JhbmRvbSA9IDA7Cisg
 ICAgICAgIC8qIE1ha2Ugc3VyZSB0byBub3QgaW5jbHVkZSBVRFAgcGFja2V0cyBpbiB0aGUgY291
 bnQuICovCisgICAgICAgIGlmIChwY2JpbmZvICE9ICZ1ZGJpbmZvKQorICAgICAgICAgICAgICAg
 IGlwcG9ydF90Y3BhbGxvY3MrKzsKKyAgICAgICAgLyoKKyAgICAgICAgICogSW5zdGVhZCBvZiBo
 YXZpbmcgdHdvIGxvb3BzIGZ1cnRoZXIgZG93biBjb3VudGluZyB1cCBvciBkb3duCisgICAgICAg
 ICAqIG1ha2Ugc3VyZSB0aGF0IGZpcnN0IGlzIGFsd2F5cyA8PSBsYXN0IGFuZCBnbyB3aXRoIG9u
 bHkgb25lCisgICAgICAgICAqIGNvZGUgcGF0aCBpbXBsZW1lbnRpbmcgYWxsIGxvZ2ljLgorICAg
 ICAgICAgKi8KKyAgICAgICAgaWYgKGZpcnN0ID4gbGFzdCkgeworICAgICAgICAgICAgICAgIGF1
 eCA9IGZpcnN0OworICAgICAgICAgICAgICAgIGZpcnN0ID0gbGFzdDsKKyAgICAgICAgICAgICAg
 ICBsYXN0ID0gYXV4OworICAgICAgICB9CisKKyAgICAgICAgLyogTWFrZSB0aGUgY29tcGlsZXIg
 aGFwcHkuICovCisgICAgICAgIGxhZGRyLnNfYWRkciA9IDA7CisgICAgICAgIGlmICgoaW5wLT5p
 bnBfdmZsYWcgJiAoSU5QX0lQVjR8SU5QX0lQVjYpKSA9PSBJTlBfSVBWNCkgeworICAgICAgICAg
 ICAgICAgIEtBU1NFUlQobGFkZHJwICE9IE5VTEwsICgiJXM6IGxhZGRycCBOVUxMIGZvciB2NCBp
 bnAgJXAiLAorICAgICAgICAgICAgICAgICAgICBfX2Z1bmNfXywgaW5wKSk7CisgICAgICAgICAg
 ICAgICAgbGFkZHIgPSAqbGFkZHJwOworICAgICAgICB9CisgICAgICAgIGxwb3J0ID0gKmxwb3J0
 cDsKKworICAgICAgICBpZiAoZG9yYW5kb20pCisgICAgICAgICAgICAgICAgKmxhc3Rwb3J0ID0g
 Zmlyc3QgKyAoYXJjNHJhbmRvbSgpICUgKGxhc3QgLSBmaXJzdCkpOworCisgICAgICAgIGNvdW50
 ID0gbGFzdCAtIGZpcnN0OworCisgICAgICAgIGRvIHsKKyAgICAgICAgICAgICAgICBpZiAoY291
 bnQtLSA8IDApICAgICAgICAvKiBjb21wbGV0ZWx5IHVzZWQ/ICovCisgICAgICAgICAgICAgICAg
 ICAgICAgICByZXR1cm4gKEVBRERSTk9UQVZBSUwpOworICAgICAgICAgICAgICAgICsrKmxhc3Rw
 b3J0OworICAgICAgICAgICAgICAgIGlmICgqbGFzdHBvcnQgPCBmaXJzdCB8fCAqbGFzdHBvcnQg
 PiBsYXN0KQorICAgICAgICAgICAgICAgICAgICAgICAgKmxhc3Rwb3J0ID0gZmlyc3Q7CisgICAg
 ICAgICAgICAgICAgbHBvcnQgPSBodG9ucygqbGFzdHBvcnQpOworCisJCWlmIChlcGhlbWVyYWwp
 IHsKKwkJICAgIC8qIElmIHdlIGFyZSB0cnlpbmcgdG8gYWxsb2NhdGUgYW4gZXBoZW1lcmFsIHBv
 cnQKKwkJICAgICAqICBudW1iZXIgZnJvbSB0aGUgY29ubmVjdCgpIGNvZGUgcGF0aCwgd2Ugd2Fu
 dCB0bworCQkgICAgICogIGVuc3VyZSB0aGF0IHRoZXJlIGlzIG5vIGRpcmVjdCBjb25mbGljdC4g
 IEl0IGlzCisJCSAgICAgKiAgT0sgdG8gcmV1c2UgYSBsb2NhbCBwb3J0IG51bWJlciBiZXR3ZWVu
 IG90aGVyd2lzZQorCQkgICAgICogIGRpc3RpbmN0IFBDQnMuICovCisJCSAgICB0bXBpbnAgPSBp
 bl9wY2Jsb29rdXBfaGFzaChwY2JpbmZvLAorCQkJCQkgICAgICAgKmZhZGRycCwgKmZwb3J0cCwK
 KwkJCQkJICAgICAgIGxhZGRyLCBscG9ydCwgMCwgTlVMTCk7CisJCX0gZWxzZSB7CisJCSAgICAv
 KiBJZiB3ZSBhcmUgdHJ5aW5nIHRvIGFsbG9jYXRlIGEgbG9jYWwgcG9ydCBudW1iZXIKKwkJICAg
 ICAqICBmcm9tIGFuIGV4cGxpY2l0IGJpbmQoKSB3aXRoIGEgd2lsZGNhcmQgbG9jYWwgcG9ydCwK
 KwkJICAgICAqICB3ZSB3YW50IHRvIGJlIGEgbGl0dGxlIG1vcmUgcmVzdHJpY3RpdmUgb24gd2hp
 Y2gKKwkJICAgICAqICBsb2NhbCBwb3J0IHdlIGNob29zZS4gKi8KKwkJICAgIHRtcGlucCA9IGlu
 X3BjYmxvb2t1cF9sb2NhbChwY2JpbmZvLCBsYWRkciwKKwkJCQkJCWxwb3J0LCB3aWxkLCBjcmVk
 KTsKKwkJfQorICAgICAgICB9IHdoaWxlICh0bXBpbnAgIT0gTlVMTCk7CisKKyAgICAgICAgaWYg
 KChpbnAtPmlucF92ZmxhZyAmIChJTlBfSVBWNHxJTlBfSVBWNikpID09IElOUF9JUFY0KQorICAg
 ICAgICAgICAgICAgIGxhZGRycC0+c19hZGRyID0gbGFkZHIuc19hZGRyOworICAgICAgICAqbHBv
 cnRwID0gbHBvcnQ7CisKKyAgICAgICAgcmV0dXJuICgwKTsKK30KKwogLyoKICAqIFNldCB1cCBh
 IGJpbmQgb3BlcmF0aW9uIG9uIGEgUENCLCBwZXJmb3JtaW5nIHBvcnQgYWxsb2NhdGlvbgogICog
 YXMgcmVxdWlyZWQsIGJ1dCBkbyBub3QgYWN0dWFsbHkgbW9kaWZ5IHRoZSBQQ0IuIENhbGxlcnMg
 Y2FuCiAgKiBlaXRoZXIgY29tcGxldGUgdGhlIGJpbmQgYnkgc2V0dGluZyBpbnBfbGFkZHIvaW5w
 X2xwb3J0IGFuZAogICogY2FsbGluZyBpbl9wY2JpbnNoYXNoKCksIG9yIHRoZXkgY2FuIGp1c3Qg
 dXNlIHRoZSByZXN1bHRpbmcKQEAgLTI2OSwxOCArMzg2LDE2IEBACiBpbnQKIGluX3BjYmJpbmRf
 c2V0dXAoc3RydWN0IGlucGNiICppbnAsIHN0cnVjdCBzb2NrYWRkciAqbmFtLCBpbl9hZGRyX3Qg
 KmxhZGRycCwKICAgICB1X3Nob3J0ICpscG9ydHAsIHN0cnVjdCB1Y3JlZCAqY3JlZCkKIHsKIAlz
 dHJ1Y3Qgc29ja2V0ICpzbyA9IGlucC0+aW5wX3NvY2tldDsKLQl1bnNpZ25lZCBzaG9ydCAqbGFz
 dHBvcnQ7CiAJc3RydWN0IHNvY2thZGRyX2luICpzaW47CiAJc3RydWN0IGlucGNiaW5mbyAqcGNi
 aW5mbyA9IGlucC0+aW5wX3BjYmluZm87CiAJc3RydWN0IGluX2FkZHIgbGFkZHI7CiAJdV9zaG9y
 dCBscG9ydCA9IDA7CiAJaW50IHdpbGQgPSAwLCByZXVzZXBvcnQgPSAoc28tPnNvX29wdGlvbnMg
 JiBTT19SRVVTRVBPUlQpOwogCWludCBlcnJvcjsKLQlpbnQgZG9yYW5kb207CiAKIAkvKgogCSAq
 IEJlY2F1c2Ugbm8gYWN0dWFsIHN0YXRlIGNoYW5nZXMgb2NjdXIgaGVyZSwgYSBnbG9iYWwgd3Jp
 dGUgbG9jayBvbgogCSAqIHRoZSBwY2JpbmZvIGlzbid0IHJlcXVpcmVkLgogCSAqLwpAQCAtMzk1
 LDk1ICs1MTAsMTQgQEAKIAkJfQogCX0KIAlpZiAoKmxwb3J0cCAhPSAwKQogCQlscG9ydCA9ICps
 cG9ydHA7CiAJaWYgKGxwb3J0ID09IDApIHsKLQkJdV9zaG9ydCBmaXJzdCwgbGFzdDsKLQkJaW50
 IGNvdW50OwotCi0JCWlmIChpbnAtPmlucF9mbGFncyAmIElOUF9ISUdIUE9SVCkgewotCQkJZmly
 c3QgPSBpcHBvcnRfaGlmaXJzdGF1dG87CS8qIHN5c2N0bCAqLwotCQkJbGFzdCAgPSBpcHBvcnRf
 aGlsYXN0YXV0bzsKLQkJCWxhc3Rwb3J0ID0gJnBjYmluZm8tPmlwaV9sYXN0aGk7Ci0JCX0gZWxz
 ZSBpZiAoaW5wLT5pbnBfZmxhZ3MgJiBJTlBfTE9XUE9SVCkgewotCQkJZXJyb3IgPSBwcml2X2No
 ZWNrX2NyZWQoY3JlZCwKLQkJCSAgICBQUklWX05FVElORVRfUkVTRVJWRURQT1JULCAwKTsKLQkJ
 CWlmIChlcnJvcikKLQkJCQlyZXR1cm4gZXJyb3I7Ci0JCQlmaXJzdCA9IGlwcG9ydF9sb3dmaXJz
 dGF1dG87CS8qIDEwMjMgKi8KLQkJCWxhc3QgID0gaXBwb3J0X2xvd2xhc3RhdXRvOwkvKiA2MDAg
 Ki8KLQkJCWxhc3Rwb3J0ID0gJnBjYmluZm8tPmlwaV9sYXN0bG93OwotCQl9IGVsc2UgewotCQkJ
 Zmlyc3QgPSBpcHBvcnRfZmlyc3RhdXRvOwkvKiBzeXNjdGwgKi8KLQkJCWxhc3QgID0gaXBwb3J0
 X2xhc3RhdXRvOwotCQkJbGFzdHBvcnQgPSAmcGNiaW5mby0+aXBpX2xhc3Rwb3J0OwotCQl9Ci0J
 CS8qCi0JCSAqIEZvciBVRFAsIHVzZSByYW5kb20gcG9ydCBhbGxvY2F0aW9uIGFzIGxvbmcgYXMg
 dGhlIHVzZXIKLQkJICogYWxsb3dzIGl0LiAgRm9yIFRDUCAoYW5kIGFzIG9mIHlldCB1bmtub3du
 KSBjb25uZWN0aW9ucywKLQkJICogdXNlIHJhbmRvbSBwb3J0IGFsbG9jYXRpb24gb25seSBpZiB0
 aGUgdXNlciBhbGxvd3MgaXQgQU5ECi0JCSAqIGlwcG9ydF90aWNrKCkgYWxsb3dzIGl0LgotCQkg
 Ki8KLQkJaWYgKGlwcG9ydF9yYW5kb21pemVkICYmCi0JCQkoIWlwcG9ydF9zdG9wcmFuZG9tIHx8
 IHBjYmluZm8gPT0gJnVkYmluZm8pKQotCQkJZG9yYW5kb20gPSAxOwotCQllbHNlCi0JCQlkb3Jh
 bmRvbSA9IDA7Ci0JCS8qCi0JCSAqIEl0IG1ha2VzIG5vIHNlbnNlIHRvIGRvIHJhbmRvbSBwb3J0
 IGFsbG9jYXRpb24gaWYKLQkJICogd2UgaGF2ZSB0aGUgb25seSBwb3J0IGF2YWlsYWJsZS4KLQkJ
 ICovCi0JCWlmIChmaXJzdCA9PSBsYXN0KQotCQkJZG9yYW5kb20gPSAwOwotCQkvKiBNYWtlIHN1
 cmUgdG8gbm90IGluY2x1ZGUgVURQIHBhY2tldHMgaW4gdGhlIGNvdW50LiAqLwotCQlpZiAocGNi
 aW5mbyAhPSAmdWRiaW5mbykKLQkJCWlwcG9ydF90Y3BhbGxvY3MrKzsKLQkJLyoKLQkJICogSW5z
 dGVhZCBvZiBoYXZpbmcgdHdvIGxvb3BzIGZ1cnRoZXIgZG93biBjb3VudGluZyB1cCBvciBkb3du
 Ci0JCSAqIG1ha2Ugc3VyZSB0aGF0IGZpcnN0IGlzIGFsd2F5cyA8PSBsYXN0IGFuZCBnbyB3aXRo
 IG9ubHkgb25lCi0JCSAqIGNvZGUgcGF0aCBpbXBsZW1lbnRpbmcgYWxsIGxvZ2ljLgotCQkgKgot
 CQkgKiBXZSBzcGxpdCB0aGUgdHdvIGNhc2VzICh1cCBhbmQgZG93bikgc28gdGhhdCB0aGUgZGly
 ZWN0aW9uCi0JCSAqIGlzIG5vdCBiZWluZyB0ZXN0ZWQgb24gZWFjaCByb3VuZCBvZiB0aGUgbG9v
 cC4KLQkJICovCi0JCWlmIChmaXJzdCA+IGxhc3QpIHsKLQkJCS8qCi0JCQkgKiBjb3VudGluZyBk
 b3duCi0JCQkgKi8KLQkJCWlmIChkb3JhbmRvbSkKLQkJCQkqbGFzdHBvcnQgPSBmaXJzdCAtCi0J
 CQkJCSAgICAoYXJjNHJhbmRvbSgpICUgKGZpcnN0IC0gbGFzdCkpOwotCQkJY291bnQgPSBmaXJz
 dCAtIGxhc3Q7Ci0KLQkJCWRvIHsKLQkJCQlpZiAoY291bnQtLSA8IDApCS8qIGNvbXBsZXRlbHkg
 dXNlZD8gKi8KLQkJCQkJcmV0dXJuIChFQUREUk5PVEFWQUlMKTsKLQkJCQktLSpsYXN0cG9ydDsK
 LQkJCQlpZiAoKmxhc3Rwb3J0ID4gZmlyc3QgfHwgKmxhc3Rwb3J0IDwgbGFzdCkKLQkJCQkJKmxh
 c3Rwb3J0ID0gZmlyc3Q7Ci0JCQkJbHBvcnQgPSBodG9ucygqbGFzdHBvcnQpOwotCQkJfSB3aGls
 ZSAoaW5fcGNibG9va3VwX2xvY2FsKHBjYmluZm8sIGxhZGRyLCBscG9ydCwKLQkJCSAgICB3aWxk
 LCBjcmVkKSk7Ci0JCX0gZWxzZSB7Ci0JCQkvKgotCQkJICogY291bnRpbmcgdXAKLQkJCSAqLwot
 CQkJaWYgKGRvcmFuZG9tKQotCQkJCSpsYXN0cG9ydCA9IGZpcnN0ICsKLQkJCQkJICAgIChhcmM0
 cmFuZG9tKCkgJSAobGFzdCAtIGZpcnN0KSk7Ci0JCQljb3VudCA9IGxhc3QgLSBmaXJzdDsKLQot
 CQkJZG8gewotCQkJCWlmIChjb3VudC0tIDwgMCkJLyogY29tcGxldGVseSB1c2VkPyAqLwotCQkJ
 CQlyZXR1cm4gKEVBRERSTk9UQVZBSUwpOwotCQkJCSsrKmxhc3Rwb3J0OwotCQkJCWlmICgqbGFz
 dHBvcnQgPCBmaXJzdCB8fCAqbGFzdHBvcnQgPiBsYXN0KQotCQkJCQkqbGFzdHBvcnQgPSBmaXJz
 dDsKLQkJCQlscG9ydCA9IGh0b25zKCpsYXN0cG9ydCk7Ci0JCQl9IHdoaWxlIChpbl9wY2Jsb29r
 dXBfbG9jYWwocGNiaW5mbywgbGFkZHIsIGxwb3J0LAotCQkJICAgIHdpbGQsIGNyZWQpKTsKLQkJ
 fQorCSAgICBlcnJvciA9IGluX3BjYl9scG9ydChpbnAsIE5VTEwsIE5VTEwsCisJCQkJICZsYWRk
 ciwgJmxwb3J0LCBjcmVkLCB3aWxkLCAwKTsKKwkgICAgaWYgKGVycm9yICE9IDApCisJCXJldHVy
 biAoZXJyb3IpOwogCX0KIAkqbGFkZHJwID0gbGFkZHIuc19hZGRyOwogCSpscG9ydHAgPSBscG9y
 dDsKIAlyZXR1cm4gKDApOwogfQpAQCAtODMwLDE0ICs4NjQsMTQgQEAKIAkJaWYgKG9pbnBwICE9
 IE5VTEwpCiAJCQkqb2lucHAgPSBvaW5wOwogCQlyZXR1cm4gKEVBRERSSU5VU0UpOwogCX0KIAlp
 ZiAobHBvcnQgPT0gMCkgewotCQllcnJvciA9IGluX3BjYmJpbmRfc2V0dXAoaW5wLCBOVUxMLCAm
 bGFkZHIuc19hZGRyLCAmbHBvcnQsCi0JCSAgICBjcmVkKTsKLQkJaWYgKGVycm9yKQotCQkJcmV0
 dXJuIChlcnJvcik7CisJICAgIGVycm9yID0gaW5fcGNiX2xwb3J0KGlucCwgJmZhZGRyLCAmZnBv
 cnQsICZsYWRkciwgJmxwb3J0LAorCQkJCSBjcmVkLCAwLCAxKTsKKwkgICAgaWYgKGVycm9yKQor
 CQlyZXR1cm4gKGVycm9yKTsKIAl9CiAJKmxhZGRycCA9IGxhZGRyLnNfYWRkcjsKIAkqbHBvcnRw
 ID0gbHBvcnQ7CiAJKmZhZGRycCA9IGZhZGRyLnNfYWRkcjsKIAkqZnBvcnRwID0gZnBvcnQ7Cgo9
 PT09IC8vZGVwb3QvYnJhbmNoL3Bpb25lZXIta2FybmVyLWQxL3NyYy9mcmVlYnNkLWMvc3lzL25l
 dGluZXQvaW5fcGNiLmgjMiAodGV4dCkgPT09PQoKQEAgLTQ5NCwxMCArNDk0LDE2IEBACiBleHRl
 cm4gc3RydWN0IGNhbGxvdXQgaXBwb3J0X3RpY2tfY2FsbG91dDsKIAogdm9pZAlpbl9wY2JwdXJn
 ZWlmMChzdHJ1Y3QgaW5wY2JpbmZvICosIHN0cnVjdCBpZm5ldCAqKTsKIGludAlpbl9wY2JhbGxv
 YyhzdHJ1Y3Qgc29ja2V0ICosIHN0cnVjdCBpbnBjYmluZm8gKik7CiBpbnQJaW5fcGNiYmluZChz
 dHJ1Y3QgaW5wY2IgKiwgc3RydWN0IHNvY2thZGRyICosIHN0cnVjdCB1Y3JlZCAqKTsKK2ludAor
 aW5fcGNiX2xwb3J0KHN0cnVjdCBpbnBjYiAqaW5wLAorCSAgICAgc3RydWN0IGluX2FkZHIgKmZh
 ZGRycCwgdV9zaG9ydCAqZnBvcnRwLAorCSAgICAgc3RydWN0IGluX2FkZHIgKmxhZGRycCwgdV9z
 aG9ydCAqbHBvcnRwLAorCSAgICAgc3RydWN0IHVjcmVkICpjcmVkLCBpbnQgd2lsZCwgaW50IGVw
 aGVtZXJhbCk7CisKIGludAlpbl9wY2JiaW5kX3NldHVwKHN0cnVjdCBpbnBjYiAqLCBzdHJ1Y3Qg
 c29ja2FkZHIgKiwgaW5fYWRkcl90ICosCiAJICAgIHVfc2hvcnQgKiwgc3RydWN0IHVjcmVkICop
 OwogaW50CWluX3BjYmNvbm5lY3Qoc3RydWN0IGlucGNiICosIHN0cnVjdCBzb2NrYWRkciAqLCBz
 dHJ1Y3QgdWNyZWQgKik7CiBpbnQJaW5fcGNiY29ubmVjdF9zZXR1cChzdHJ1Y3QgaW5wY2IgKiwg
 c3RydWN0IHNvY2thZGRyICosIGluX2FkZHJfdCAqLAogCSAgICB1X3Nob3J0ICosIGluX2FkZHJf
 dCAqLCB1X3Nob3J0ICosIHN0cnVjdCBpbnBjYiAqKiwKCj09PT0gLy9kZXBvdC9icmFuY2gvcGlv
 bmVlci1rYXJuZXItZDEvc3JjL2ZyZWVic2QtYy9zeXMvbmV0aW5ldC90Y3BfdXNycmVxLmMjMiAo
 dGV4dCkgPT09PQoKQEAgLTEwNTYsMTggKzEwNTYsMTcgQEAKIAlzdHJ1Y3QgaW5wY2IgKmlucCA9
 IHRwLT50X2lucGNiLCAqb2lucDsKIAlzdHJ1Y3Qgc29ja2V0ICpzbyA9IGlucC0+aW5wX3NvY2tl
 dDsKIAlzdHJ1Y3QgaW5fYWRkciBsYWRkcjsKIAl1X3Nob3J0IGxwb3J0OwogCWludCBlcnJvcjsK
 KwlpbnQgd2FzX2JvdW5kID0gMTsKIAogCUlOUF9JTkZPX1dMT0NLX0FTU0VSVCgmdGNiaW5mbyk7
 CiAJSU5QX1dMT0NLX0FTU0VSVChpbnApOwogCiAJaWYgKGlucC0+aW5wX2xwb3J0ID09IDApIHsK
 LQkJZXJyb3IgPSBpbl9wY2JiaW5kKGlucCwgKHN0cnVjdCBzb2NrYWRkciAqKTAsIHRkLT50ZF91
 Y3JlZCk7Ci0JCWlmIChlcnJvcikKLQkJCXJldHVybiBlcnJvcjsKKwkgICAgd2FzX2JvdW5kID0g
 MDsKIAl9CiAKIAkvKgogCSAqIENhbm5vdCBzaW1wbHkgY2FsbCBpbl9wY2Jjb25uZWN0LCBiZWNh
 dXNlIHRoZXJlIG1pZ2h0IGJlIGFuCiAJICogZWFybGllciBpbmNhcm5hdGlvbiBvZiB0aGlzIHNh
 bWUgY29ubmVjdGlvbiBzdGlsbCBpbgpAQCAtMTA4MCwxMSArMTA3OSwxNyBAQAogCWlmIChlcnJv
 ciAmJiBvaW5wID09IE5VTEwpCiAJCXJldHVybiBlcnJvcjsKIAlpZiAob2lucCkKIAkJcmV0dXJu
 IEVBRERSSU5VU0U7CiAJaW5wLT5pbnBfbGFkZHIgPSBsYWRkcjsKLQlpbl9wY2JyZWhhc2goaW5w
 KTsKKwlpZiAod2FzX2JvdW5kKSB7CisJICAgIEtBU1NFUlQoaW5wLT5pbnBfbHBvcnQgPT0gbHBv
 cnQsICgidGNwX2Nvbm5lY3Q6IGxwb3J0IGNoYW5nZWQiKSk7CisJICAgIGluX3BjYnJlaGFzaChp
 bnApOworCX0gZWxzZSB7CisJICAgIGlucC0+aW5wX2xwb3J0ID0gbHBvcnQ7CisJICAgIGluX3Bj
 Ymluc2hhc2goaW5wKTsKKwl9CiAKIAkvKgogCSAqIENvbXB1dGUgd2luZG93IHNjYWxpbmcgdG8g
 cmVxdWVzdDoKIAkgKiBTY2FsZSB0byBmaXQgaW50byBzd2VldCBzcG90LiAgU2VlIHRjcF9zeW5j
 YWNoZS5jLgogCSAqIFhYWDogVGhpcyBzaG91bGQgbW92ZSB0byB0Y3Bfb3V0cHV0KCkuCg==
 
 --_002_CCEE0CF314A51karnerpanasascom_--
>Unformatted:
