RPC cannot decode arguments for TCP transport

I am working on a multi-threaded RPC server using the example from this page: http://bderzhavets.blogspot.ca/2005/11/multithreaded-rpc-server-in-white-box.html

Unfortunately, this was not entirely correct, and after pursuing errors for some time, I found that the server could not decode the arguments (based on the return code from squareproc_2). Server-side execution seems to stop after a call squareproc_2_svcto a function serv_request. See the case: SQUAREPROCcode below from square_svc.c

void *serv_request(void *data)
{
    struct thr_data *ptr_data = (struct thr_data *)data;
    {
        square_in argument;
        square_out result;
        bool_t retval;
        xdrproc_t _xdr_argument, _xdr_result;
        bool_t (*local)(char *, void *, struct svc_req *);
        struct svc_req *rqstp = ptr_data->rqstp;
        register SVCXPRT *transp = ptr_data->transp;
        switch (rqstp->rq_proc) {
            case NULLPROC:
                printf("NULLPROC called\n");
                (void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL);
                return;
            case SQUAREPROC:
                _xdr_argument = (xdrproc_t) xdr_square_in;
                _xdr_result = (xdrproc_t) xdr_square_out;
                printf("_xdr_result = %ld\n",_xdr_result);
                local = (bool_t (*) (char *, void *,  struct svc_req *))squareproc_2_svc;
                break;
            default:
                printf("default case executed");
                svcerr_noproc (transp);
                return;
        }
        memset ((void *)&argument, 0, sizeof (argument));
        if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
            printf("svc_getargs failed");
            svcerr_decode (transp);
            return;
        }
        retval = (bool_t) (*local)((char *)&argument, (void *)&result, rqstp);
        printf("serv_request result: %d\n",retval);
        if (retval > 0 && !svc_sendreply(transp, (xdrproc_t) _xdr_result, (char *)&result))
        {
            printf("something happened...\n");
            svcerr_systemerr (transp);
        }
        if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
            fprintf (stderr, "%s", "unable to free arguments");
            exit (1);
        }
        if (!square_prog_2_freeresult (transp, _xdr_result, (caddr_t) &result))
            fprintf (stderr, "%s", "unable to free results");
        return;
    }
}

Here is the implementation squareproc_2_svcfrom square_server.c:

bool_t squareproc_2_svc(square_in *inp,square_out *outp,struct svc_req *rqstp)
{
    printf("Thread id = '%ld' started, arg = %ld\n",pthread_self(),inp->arg1);
    sleep(5);
    outp->res1=inp->arg1*inp->arg1;
    printf("Thread id = '%ld' is done %ld \n",pthread_self(),outp->res1);
    return(TRUE);
}

Client side output:

yak@AcerPC:~/RPC/multithread_example$ ./ClientSQUARE localhost 2
squareproc_2 called
xdr_square_in result: 1
function call failed; code: 11

Output to the server side:

yak@AcerPC:~/RPC/multithread_example$ sudo ./ServerSQUARE 
creating threads
SQUAREPROC called
xdr_square_in result: 0

As you can see, xdr_square_in returns a FALSE result on the server side. Here is the .x square

struct square_in {
    long arg1;
};

struct square_out {
    long res1;
};

program SQUARE_PROG {
    version SQUARE_VERS {
        square_out SQUAREPROC(square_in) = 1;
    } = 2 ;
} = 0x31230000;

and square_xdr.c

/*
 * Please do not edit this file.
 * It was generated using rpcgen.
 */

#include "square.h"

bool_t
xdr_square_in (XDR *xdrs, square_in *objp)
{
    register int32_t *buf;
    int retval;
    if (!xdr_long (xdrs, &objp->arg1)) retval = FALSE;
    else retval = TRUE;
    printf("xdr_square_in result: %d\n",retval);
    return retval;
}

bool_t
xdr_square_out (XDR *xdrs, square_out *objp)
{
    register int32_t *buf;
    int retval;
    if (!xdr_long (xdrs, &objp->res1)) retval = FALSE;
    else retval = TRUE;
    printf("xdr_square_out result: %d\n",retval);
    return retval;
}

Ubuntu 14.04 LTS, xdr- rpcgen -a -M gcc.

TCP . UDP , , . 15 . UDP 10 , 2 10 squareproc_2.

+4
1

.

xen, pthread_create _prog_2, pthread_attr_setdetachstate, pthread_attr_init. , attr / - .

square_prog_2 : rqstp transp. malloc'ed struct data_str [ ]. , rqstp transp (, printf ( "% p" )). [ , pthread_mutex_lock]. Malloc rqstp/transp, , , , , .

11. , SIGSEGV . rqstp/transp.

, , , XDR - . , , svc_ * /.

. , squ_prog_2 serv_request (, pthread_ *). , .

, - - segfault .. ( x * x), .

. / XDR. svc_run - . (, x * x) /req/transp ..

:

while (1) {
    if (svc_getreq_poll()) {
        // parse XDR
        // create data/return struct for child thread
        // create thread
        // add struct to list of "in-flight" requests
    }

    forall struct in inflight {
        if (reqdone) {
            // take result from struct
            // encode into XDR
            // do send_reply
            // remove struct from list
        }
    }
}

:

struct child_struct {
    int num;
    int num_squared;
};

: ptr->num_squared = ptr->num * ptr->num

UPDATE: RPC Linux FreeBSD

: https://www.redhat.com/archives/redhat-list/2004-June/msg00439.html .

: - rpcgen Linux. SunOS RPC RPC- Linux

Linux rpcgen: http://linux.die.net/man/1/rpcgen -M. IMO, , rpcgen , , .

FreeBSD [ ]: http://www.freebsd.org/cgi/man.cgi?query=rpcgen&sektion=1&manpath=FreeBSD+5.0-RELEASE . -M :

M -         rpcgen .         , . rpc_svc_calls (3) ,        , rpcgen MT.

:

RPC/XDR? , . , , .

. , . , , , . , endian, bswap_32.

, :

struct msgcontrol {
    int what_i_am;
    int operation_to_perform;
    int payload_length;
    int payload[0];
};

: (, MPI ), , , setsockopt, - ,

, , , , MPI . , , . , .

+4

Source: https://habr.com/ru/post/1612153/


All Articles