void *my_thread_process(void *arg) { CLIENT *client = NULL; struct netconfig *nconf = NULL; struct netbuf svcaddr; char addrbuf[ADDRBUFSIZE]; enum clnt_stat cs; int var_snd = 10; int var_rec = -1; struct timeval tv; int i; if (run_mode == 1) { fprintf(stderr, "Thread %d\n", atoi(arg)); } tv.tv_sec = 0; tv.tv_usec = 100; nconf = getnetconfigent("udp"); if (nconf == (struct netconfig *)NULL) { //syslog(LOG_ERR, "getnetconfigent for udp failed"); printf("err nconf\n"); pthread_exit(1); } svcaddr.len = 0; svcaddr.maxlen = ADDRBUFSIZE; svcaddr.buf = addrbuf; if (svcaddr.buf == NULL) { pthread_exit(1); } //printf("svcaddr reserved (%s)\n", argc[1]); if (!rpcb_getaddr(progNum + atoi(arg), VERSNUM, nconf, &svcaddr, hostname)) { fprintf(stderr, "rpcb_getaddr failed!!\n"); pthread_exit(1); } //printf("svc get\n"); client = clnt_dg_create(RPC_ANYFD, &svcaddr, progNum + atoi(arg), VERSNUM, 1024, 1024); if (client == NULL) { clnt_pcreateerror("ERR"); pthread_exit(1); } for (i = 0; i < callNb; i++) { cs = clnt_call(client, PROCNUM, (xdrproc_t) xdr_int, (char *)&var_snd, (xdrproc_t) xdr_int, (char *)&var_rec, tv); thread_array_result[atoi(arg)] += (cs == RPC_SUCCESS); } pthread_exit(0); }
void *my_thread_process(void *arg) { int i; CLIENT *clnt = NULL; struct datas vars; static double result = 0; struct timeval total_timeout; struct netconfig *nconf = NULL; struct netbuf svcaddr; char addrbuf[ADDRBUFSIZE]; total_timeout.tv_sec = 1; total_timeout.tv_usec = 1; nconf = getnetconfigent("udp"); if ((struct netconfig *)nconf == NULL) { //Test failed printf("5\n"); pthread_exit(5); } svcaddr.len = 0; svcaddr.maxlen = ADDRBUFSIZE; svcaddr.buf = addrbuf; if (svcaddr.buf == NULL) { printf("5\n"); pthread_exit(5); } if (!rpcb_getaddr(progNum, VERSNUM, nconf, &svcaddr, hostname)) { fprintf(stderr, "rpcb_getaddr failed!!\n"); printf("5\n"); pthread_exit(5); } clnt = clnt_dg_create(RPC_ANYFD, &svcaddr, progNum, VERSNUM, 1024, 1024); if (clnt == NULL) { printf("5\n"); pthread_exit(5); } if (run_mode == 1) { fprintf(stderr, "Thread %d\n", atoi(arg)); } vars.a = getRand(); vars.b = getRand(); vars.c = getRand(); resTbl[atoi(arg)].locRes = vars.a + (vars.b * vars.c); clnt_call((CLIENT *) clnt, CALCTHREADPROC, (xdrproc_t) xdr_datas, (char *)&vars, // xdr_in (xdrproc_t) xdr_double, (char *)&resTbl[atoi(arg)].svcRes, // xdr_out total_timeout); thread_array_result[atoi(arg)] = (resTbl[atoi(arg)].svcRes == resTbl[atoi(arg)].locRes) ? 0 : 1; if (run_mode == 1) { fprintf(stderr, "Thread #%d calc : %lf, received : %lf\n", atoi(arg), resTbl[atoi(arg)].locRes, resTbl[atoi(arg)].svcRes); } pthread_exit(0); }
int main(int argn, char *argc[]) { //Program parameters : argc[1] : HostName or Host IP // argc[2] : Server Program Number // other arguments depend on test case //run_mode can switch into stand alone program or program launch by shell script //1 : stand alone, debug mode, more screen information //0 : launch by shell script as test case, only one printf -> result status int run_mode = 0; int test_status = 1; //Default test result set to FAILED int progNum = atoi(argc[2]); CLIENT *client = NULL; struct netconfig *nconf = NULL; struct netbuf svcaddr; char addrbuf[ADDRBUFSIZE]; bool_t rpcb_rslt; //Initialization if (run_mode) { printf("Before creation\n"); printf("client : %d\n", client); printf("nconf : %d\n", nconf); } nconf = getnetconfigent("udp"); if (nconf == (struct netconfig *) NULL) { //syslog(LOG_ERR, "getnetconfigent for udp failed"); fprintf(stderr, "err nconf\n"); printf("5\n"); exit(1); } svcaddr.len = 0; svcaddr.maxlen = ADDRBUFSIZE; svcaddr.buf = addrbuf; if (svcaddr.buf == NULL) { /* if malloc() failed, print error messages and exit */ printf("5\n"); return 1; } //printf("svcaddr reserved (%s)\n", argc[1]); if (!rpcb_getaddr(progNum, VERSNUM, nconf, &svcaddr, argc[1])) { fprintf(stderr, "rpcb_getaddr failed!!\n"); printf("5\n"); exit(1); } //printf("svc get\n"); client = clnt_dg_create(RPC_ANYFD, &svcaddr, progNum, VERSNUM, 1024, 1024);/**/ test_status = ((CLIENT *)client != NULL) ? 0 : 1; //This last printf gives the result status to the tests suite //normally should be 0: test has passed or 1: test has failed printf("%d\n", test_status); return test_status; }
int main(int argn, char *argc[]) { //Program parameters : argc[1] : HostName or Host IP // argc[2] : Server Program Number // argc[3] : Number of test call // other arguments depend on test case //run_mode can switch into stand alone program or program launch by shell script //1 : stand alone, debug mode, more screen information //0 : launch by shell script as test case, only one printf -> result status int run_mode = 0; int test_status = 0; //Default test result set to FAILED int i; double *resultTbl; struct timeval tv1, tv2; struct timezone tz; long long diff; double rslt; int progNum = atoi(argc[2]); CLIENT *client = NULL; struct netconfig *nconf = NULL; struct netbuf svcaddr; char addrbuf[ADDRBUFSIZE]; enum clnt_stat cs; int var_snd = 0; int var_rec = -1; struct timeval tv; //Test initialisation maxIter = atoi(argc[3]); resultTbl = malloc(maxIter * sizeof(double)); tv.tv_sec = 0; tv.tv_usec = 100; nconf = getnetconfigent("udp"); if (nconf == NULL) { //syslog(LOG_ERR, "getnetconfigent for udp failed"); fprintf(stderr, "err nconf\n"); printf("5\n"); exit(1); } svcaddr.len = 0; svcaddr.maxlen = ADDRBUFSIZE; svcaddr.buf = addrbuf; if (svcaddr.buf == NULL) { /* if malloc() failed, print error messages and exit */ printf("5\n"); exit(1); } //printf("svcaddr reserved (%s)\n", argc[1]); if (!rpcb_getaddr(progNum, VERSNUM, nconf, &svcaddr, argc[1])) { fprintf(stderr, "rpcb_getaddr failed!!\n"); printf("5\n"); exit(1); } //printf("svc get\n"); client = clnt_dg_create(RPC_ANYFD, &svcaddr, progNum, VERSNUM, 1024, 1024); if (client == NULL) { clnt_pcreateerror("ERR"); exit(1); } //Call tested function several times for (i = 0; i < maxIter; i++) { //Tic gettimeofday(&tv1, &tz); //Call function cs = clnt_call(client, PROCNUM, (xdrproc_t) xdr_int, (char *)&var_snd, (xdrproc_t) xdr_int, (char *)&var_rec, tv); //Toc gettimeofday(&tv2, &tz); //Add function execution time (toc-tic) diff = (tv2.tv_sec - tv1.tv_sec) * 1000000L + (tv2.tv_usec - tv1.tv_usec); rslt = (double)diff / 1000; if (cs == RPC_SUCCESS) { resultTbl[i] = rslt; } else { test_status = 1; break; } if (run_mode) { fprintf(stderr, "lf time = %lf usecn\n", resultTbl[i]); } } //This last printf gives the result status to the tests suite //normally should be 0: test has passed or 1: test has failed printf("%d\n", test_status); printf("%lf %d\n", average(resultTbl), maxIter); printf("%lf\n", mini(resultTbl)); printf("%lf\n", maxi(resultTbl)); return test_status; }
int main(int argn, char *argc[]) { //Program parameters : argc[1] : HostName or Host IP // argc[2] : Server Program Number // other arguments depend on test case //run_mode can switch into stand alone program or program launch by shell script //1 : stand alone, debug mode, more screen information //0 : launch by shell script as test case, only one printf -> result status int run_mode = 0; int test_status = 0; //Default test result set to PASS int progNum = atoi(argc[2]); int i; params paramList[NBCASE]; CLIENT *client = NULL; struct netconfig *nconf = NULL; struct netbuf svcaddr; char addrbuf[ADDRBUFSIZE]; bool_t rpcb_rslt; //Test initialization nconf = getnetconfigent("udp"); if (nconf == (struct netconfig *)NULL) { //syslog(LOG_ERR, "getnetconfigent for udp failed"); fprintf(stderr, "err nconf\n"); printf("5\n"); exit(1); } svcaddr.len = 0; svcaddr.maxlen = ADDRBUFSIZE; svcaddr.buf = addrbuf; if (svcaddr.buf == NULL) { /* if malloc() failed, print error messages and exit */ printf("5\n"); return 1; } if (!rpcb_getaddr(progNum, VERSNUM, nconf, &svcaddr, argc[1])) { fprintf(stderr, "rpcb_getaddr failed!!\n"); printf("5\n"); exit(1); } //Test arguments initialization paramList[0].bufsnd = 0; paramList[0].bufrec = 0; paramList[1].bufsnd = 0; paramList[1].bufrec = 2147483647; paramList[2].bufsnd = 2147483647; paramList[2].bufrec = 0; paramList[3].bufsnd = 2147483647; paramList[3].bufrec = 2147483647; //Call tested function using all tests cases for (i = 0; i < NBCASE; i++) { //Debug mode prints if (run_mode == 1) { printf("Test using values : %d ", paramList[i].bufsnd); printf("%d", paramList[i].bufrec); printf("\n"); } //Call function client = clnt_dg_create(RPC_ANYFD, &svcaddr, progNum, VERSNUM, paramList[i].bufsnd, paramList[i].bufrec); //Check result if (client == NULL) { //test has failed test_status = 1; break; } } //This last printf gives the result status to the tests suite //normally should be 0: test has passed or 1: test has failed printf("%d\n", test_status); return test_status; }
int main(int argn, char *argc[]) { //Program parameters : argc[1] : HostName or Host IP // argc[2] : Server Program Number // argc[3] : Number of testes function calls // other arguments depend on test case //run_mode can switch into stand alone program or program launch by shell script //1 : stand alone, debug mode, more screen information //0 : launch by shell script as test case, only one printf -> result status int run_mode = 0; int test_status = 1; //Default test result set to FAILED int progNum = atoi(argc[2]); CLIENT *client = NULL; struct netconfig *nconf = NULL; struct netbuf svcaddr; char addrbuf[ADDRBUFSIZE]; enum clnt_stat cs; int var_snd = 10; int var_rec = -1; struct timeval tv; int nbCall = atoi(argc[3]); int nbOk = 0; int i; //Initialization if (run_mode) { printf("Before creation\n"); printf("client : %d\n", client); printf("nconf : %d\n", nconf); } tv.tv_sec = 0; tv.tv_usec = 100; nconf = getnetconfigent("udp"); if (nconf == (struct netconfig *)NULL) { //syslog(LOG_ERR, "getnetconfigent for udp failed"); printf("err nconf\n"); exit(1); } svcaddr.len = 0; svcaddr.maxlen = ADDRBUFSIZE; svcaddr.buf = addrbuf; if (svcaddr.buf == NULL) { /* if malloc() failed, print error messages and exit */ printf("5\n"); exit(1); } //printf("svcaddr reserved (%s)\n", argc[1]); if (!rpcb_getaddr(progNum, VERSNUM, nconf, &svcaddr, argc[1])) { fprintf(stderr, "rpcb_getaddr failed!!\n"); exit(1); } //printf("svc get\n"); client = clnt_dg_create(RPC_ANYFD, &svcaddr, progNum, VERSNUM, 1024, 1024); for (i = 0; i < nbCall; i++) { cs = clnt_call((CLIENT *) client, PROCNUM, (xdrproc_t) xdr_int, (char *)&var_snd, // xdr_in (xdrproc_t) xdr_int, (char *)&var_rec, // xdr_out tv); if (cs == RPC_SUCCESS) nbOk++; } if (run_mode == 1) { printf("Aimed : %d\n", nbCall); printf("Got : %d\n", nbOk); } test_status = (nbOk == nbCall) ? 0 : 1; //This last printf gives the result status to the tests suite //normally should be 0: test has passed or 1: test has failed printf("%d\n", test_status); clnt_destroy(client); return test_status; }
/* * Generic client creation: returns client handle. * Default options are set, which the user can * change using the rpc equivalent of _ioctl()'s : clnt_control(). * If fd is RPC_ANYFD, it will be opened using nconf. * It will be bound if not so. * If sizes are 0; appropriate defaults will be chosen. */ CLIENT * clnt_tli_create(int fd, const struct netconfig *nconf, struct netbuf *svcaddr, rpcprog_t prog, rpcvers_t vers, uint sendsz, uint recvsz) { CLIENT *cl; /* client handle */ bool_t madefd = FALSE; /* whether fd opened here */ long servtype; int one = 1; struct __rpc_sockinfo si; extern int __rpc_minfd; if (fd == RPC_ANYFD) { if (nconf == NULL) { rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; return (NULL); } fd = __rpc_nconf2fd(nconf); if (fd == -1) goto err; if (fd < __rpc_minfd) fd = __rpc_raise_fd(fd); madefd = TRUE; servtype = nconf->nc_semantics; if (!__rpc_fd2sockinfo(fd, &si)) goto err; bindresvport(fd, NULL); } else { if (!__rpc_fd2sockinfo(fd, &si)) goto err; servtype = __rpc_socktype2seman(si.si_socktype); if (servtype == -1) { rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; return (NULL); } } if (si.si_af != ((struct sockaddr *)svcaddr->buf)->sa_family) { rpc_createerr.cf_stat = RPC_UNKNOWNHOST; /* XXX */ goto err1; } switch (servtype) { case NC_TPI_COTS: cl = clnt_vc_create(fd, svcaddr, prog, vers, sendsz, recvsz); break; case NC_TPI_COTS_ORD: if (nconf && ((strcmp(nconf->nc_protofmly, "inet") == 0) || (strcmp(nconf->nc_protofmly, "inet6") == 0))) { setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof (one)); } cl = clnt_vc_create(fd, svcaddr, prog, vers, sendsz, recvsz); break; case NC_TPI_CLTS: cl = clnt_dg_create(fd, svcaddr, prog, vers, sendsz, recvsz); break; default: goto err; } if (cl == NULL) goto err1; /* borrow errors from clnt_dg/vc creates */ if (nconf) { cl->cl_netid = strdup(nconf->nc_netid); cl->cl_tp = strdup(nconf->nc_device); } else { cl->cl_netid = ""; cl->cl_tp = ""; } if (madefd) { (void) CLNT_CONTROL(cl, CLSET_FD_CLOSE, NULL); /* (void) CLNT_CONTROL(cl, CLSET_POP_TIMOD, NULL); */ }; return (cl); err: rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = errno; err1: if (madefd) (void)close(fd); return (NULL); }
int main(int argn, char *argc[]) { //Program parameters : argc[1] : HostName or Host IP // argc[2] : Server Program Number // other arguments depend on test case //run_mode can switch into stand alone program or program launch by shell script //1 : stand alone, debug mode, more screen information //0 : launch by shell script as test case, only one printf -> result status int run_mode = 0; int test_status = 0; //Default test result set to PASSED int progNum = atoi(argc[2]); CLIENT *client = NULL; struct netconfig *nconf = NULL; struct netbuf svcaddr; char addrbuf[ADDRBUFSIZE]; enum clnt_stat cs; struct timeval tv; //Sent variables int intSnd; double dblSnd; long lngSnd; char *strSnd; //Received variables int intRec; double dblRec; long lngRec; char *strRec; //Test initialization tv.tv_sec = 0; tv.tv_usec = 100; nconf = getnetconfigent("udp"); if (nconf == (struct netconfig *) NULL) { //syslog(LOG_ERR, "getnetconfigent for udp failed"); fprintf(stderr, "err nconf\n"); printf("5\n"); exit(1); } svcaddr.len = 0; svcaddr.maxlen = ADDRBUFSIZE; svcaddr.buf = addrbuf; if (svcaddr.buf == (char *)NULL) { /* if malloc() failed, print error messages and exit */ printf("5\n"); exit(1); } //printf("svcaddr reserved (%s)\n", argc[1]); if (!rpcb_getaddr(progNum, VERSNUM, nconf, &svcaddr, argc[1])) { fprintf(stderr, "rpcb_getaddr failed!!\n"); printf("5\n"); exit(1); } //printf("svc get\n"); client = clnt_dg_create(RPC_ANYFD, &svcaddr, progNum, VERSNUM, 1024, 1024); if (client == (CLIENT *)NULL) { clnt_pcreateerror("ERR"); exit(1); } //Call tested procedure several times //Int test : call INTPROCNUM RPC intSnd = -65536; cs = clnt_call(client, INTPROCNUM, (xdrproc_t)xdr_int, (char *)&intSnd, (xdrproc_t)xdr_int, (char *)&intRec, tv); if (intSnd != intRec) test_status = 1; if (run_mode == 1) printf("Send (int) : %d, Received : %d\n", intSnd, intRec); //Test positive number intSnd = 16777216; cs = clnt_call(client, INTPROCNUM, (xdrproc_t)xdr_int, (char *)&intSnd, (xdrproc_t)xdr_int, (char *)&intRec, tv); if (intSnd != intRec) test_status = 1; if (run_mode == 1) printf("Send (int) : %d, Received : %d\n", intSnd, intRec); //Long test : call LNGPROCNUM RPC lngSnd = -430000; cs = clnt_call(client, LNGPROCNUM, (xdrproc_t)xdr_long, (char *)&lngSnd, (xdrproc_t)xdr_long, (char *)&lngRec, tv); if (lngSnd != lngRec) test_status = 1; if (run_mode == 1) printf("Send (long) : %ld, Received : %ld\n", lngSnd, lngRec); //Double test : call DBLPROCNUM RPC dblSnd = -1735.63000f; cs = clnt_call(client, DBLPROCNUM, (xdrproc_t)xdr_double, (char *)&dblSnd, (xdrproc_t)xdr_double, (char *)&dblRec, tv); if (dblSnd != dblRec) test_status = 1; if (run_mode == 1) printf("Send (double) : %lf, Received : %lf\n", dblSnd, dblRec); //String test : call STRPROCNUM RPC strSnd = "text to send."; strRec = (char *)malloc(64 * sizeof(char)); cs = clnt_call(client, STRPROCNUM, (xdrproc_t)xdr_wrapstring, (char *)&strSnd, (xdrproc_t)xdr_wrapstring, (char *)&strRec, tv); if (strcmp(strSnd, strRec)) test_status = 1; if (run_mode == 1) printf("Send (string) : %s, Received : %s\n", strSnd, strRec); //This last printf gives the result status to the tests suite //normally should be 0: test has passed or 1: test has failed printf("%d\n", test_status); return test_status; }
/* Create a channel for a new clientid (v4) or session, optionally * connecting it */ int nfs_rpc_create_chan_v40(nfs_client_id_t *pclientid, uint32_t flags) { struct netbuf raddr; int fd, proto, code = 0; rpc_call_channel_t *chan = &pclientid->cid_cb.cb_u.v40.cb_chan; assert(! chan->clnt); /* XXX we MUST error RFC 3530bis, sec. 3.3.3 */ if (! supported_auth_flavor(pclientid->cid_credential.flavor)) { code = EINVAL; goto out; } chan->type = RPC_CHAN_V40; chan->nvu.v40.pclientid = pclientid; code = nfs_clid_connected_socket(pclientid, &fd, &proto); if (code) { LogWarn(COMPONENT_NFS_CB, "Failed creating socket"); goto out; } raddr.buf = &pclientid->cid_cb.cid_addr.ss; switch (proto) { case IPPROTO_TCP: raddr.maxlen = raddr.len = sizeof(struct sockaddr_in); chan->clnt = clnt_vc_create(fd, &raddr, pclientid->cid_cb.cid_program, 1 /* Errata ID: 2291 */, 0, 0); break; case IPPROTO_UDP: raddr.maxlen = raddr.len = sizeof(struct sockaddr_in6); chan->clnt = clnt_dg_create(fd, &raddr, pclientid->cid_cb.cid_program, 1 /* Errata ID: 2291 */, 0, 0); break; default: break; } if (! chan->clnt) { code = EINVAL; goto out; } /* channel protection */ if (! nfs_rpc_callback_seccreate(chan)) { /* XXX */ code = EINVAL; } out: return (code); }
static enum clnt_stat clnt_reconnect_connect(CLIENT *cl) { struct thread *td = curthread; struct rc_data *rc = (struct rc_data *)cl->cl_private; struct socket *so; enum clnt_stat stat; int error; int one = 1; struct ucred *oldcred; CLIENT *newclient = NULL; mtx_lock(&rc->rc_lock); while (rc->rc_connecting) { error = msleep(rc, &rc->rc_lock, rc->rc_intr ? PCATCH : 0, "rpcrecon", 0); if (error) { mtx_unlock(&rc->rc_lock); return (RPC_INTR); } } if (rc->rc_closed) { mtx_unlock(&rc->rc_lock); return (RPC_CANTSEND); } if (rc->rc_client) { mtx_unlock(&rc->rc_lock); return (RPC_SUCCESS); } /* * My turn to attempt a connect. The rc_connecting variable * serializes the following code sequence, so it is guaranteed * that rc_client will still be NULL after it is re-locked below, * since that is the only place it is set non-NULL. */ rc->rc_connecting = TRUE; mtx_unlock(&rc->rc_lock); oldcred = td->td_ucred; td->td_ucred = rc->rc_ucred; so = __rpc_nconf2socket(rc->rc_nconf); if (!so) { stat = rpc_createerr.cf_stat = RPC_TLIERROR; rpc_createerr.cf_error.re_errno = 0; td->td_ucred = oldcred; goto out; } if (rc->rc_privport) bindresvport(so, NULL); if (rc->rc_nconf->nc_semantics == NC_TPI_CLTS) newclient = clnt_dg_create(so, (struct sockaddr *) &rc->rc_addr, rc->rc_prog, rc->rc_vers, rc->rc_sendsz, rc->rc_recvsz); else newclient = clnt_vc_create(so, (struct sockaddr *) &rc->rc_addr, rc->rc_prog, rc->rc_vers, rc->rc_sendsz, rc->rc_recvsz, rc->rc_intr); td->td_ucred = oldcred; if (!newclient) { soclose(so); rc->rc_err = rpc_createerr.cf_error; stat = rpc_createerr.cf_stat; goto out; } CLNT_CONTROL(newclient, CLSET_FD_CLOSE, 0); CLNT_CONTROL(newclient, CLSET_CONNECT, &one); CLNT_CONTROL(newclient, CLSET_TIMEOUT, &rc->rc_timeout); CLNT_CONTROL(newclient, CLSET_RETRY_TIMEOUT, &rc->rc_retry); CLNT_CONTROL(newclient, CLSET_WAITCHAN, rc->rc_waitchan); CLNT_CONTROL(newclient, CLSET_INTERRUPTIBLE, &rc->rc_intr); if (rc->rc_backchannel != NULL) CLNT_CONTROL(newclient, CLSET_BACKCHANNEL, rc->rc_backchannel); stat = RPC_SUCCESS; out: mtx_lock(&rc->rc_lock); KASSERT(rc->rc_client == NULL, ("rc_client not null")); if (!rc->rc_closed) { rc->rc_client = newclient; newclient = NULL; } rc->rc_connecting = FALSE; wakeup(rc); mtx_unlock(&rc->rc_lock); if (newclient) { /* * It has been closed, so discard the new client. * nb: clnt_[dg|vc]_close()/clnt_[dg|vc]_destroy() cannot * be called with the rc_lock mutex held, since they may * msleep() while holding a different mutex. */ CLNT_CLOSE(newclient); CLNT_RELEASE(newclient); } return (stat); }
/* * Create an rpc client attached to the mount daemon. */ CLIENT * get_mount_client(char *host, struct sockaddr_in *unused_sin, struct timeval *tv, int *sock, u_long mnt_version) { CLIENT *client; struct netbuf nb; struct netconfig *nc = NULL; struct sockaddr_in sin; nb.maxlen = sizeof(sin); nb.buf = (char *) &sin; /* * First try a TCP handler */ /* * Find mountd address on TCP */ if ((nc = getnetconfigent(NC_TCP)) == NULL) { plog(XLOG_ERROR, "getnetconfig for tcp failed: %s", nc_sperror()); goto tryudp; } if (!rpcb_getaddr(MOUNTPROG, mnt_version, nc, &nb, host)) { /* * don't print error messages here, since mountd might legitimately * serve udp only */ goto tryudp; } /* * Create privileged TCP socket */ *sock = t_open(nc->nc_device, O_RDWR, 0); if (*sock < 0) { plog(XLOG_ERROR, "t_open %s: %m", nc->nc_device); goto tryudp; } if (bind_resv_port(*sock, (u_short *) 0) < 0) plog(XLOG_ERROR, "couldn't bind mountd socket to privileged port"); if ((client = clnt_vc_create(*sock, &nb, MOUNTPROG, mnt_version, 0, 0)) == (CLIENT *) NULL) { plog(XLOG_ERROR, "clnt_vc_create failed"); t_close(*sock); goto tryudp; } /* tcp succeeded */ dlog("get_mount_client: using tcp, port %d", sin.sin_port); if (nc) freenetconfigent(nc); return client; tryudp: /* first free possibly previously allocated netconfig entry */ if (nc) freenetconfigent(nc); /* * TCP failed so try UDP */ /* * Find mountd address on UDP */ if ((nc = getnetconfigent(NC_UDP)) == NULL) { plog(XLOG_ERROR, "getnetconfig for udp failed: %s", nc_sperror()); goto badout; } if (!rpcb_getaddr(MOUNTPROG, mnt_version, nc, &nb, host)) { plog(XLOG_ERROR, "%s", clnt_spcreateerror("couldn't get mountd address on udp")); goto badout; } /* * Create privileged UDP socket */ *sock = t_open(nc->nc_device, O_RDWR, 0); if (*sock < 0) { plog(XLOG_ERROR, "t_open %s: %m", nc->nc_device); goto badout; /* neither tcp not udp succeeded */ } if (bind_resv_port(*sock, (u_short *) 0) < 0) plog(XLOG_ERROR, "couldn't bind mountd socket to privileged port"); if ((client = clnt_dg_create(*sock, &nb, MOUNTPROG, mnt_version, 0, 0)) == (CLIENT *) NULL) { plog(XLOG_ERROR, "clnt_dg_create failed"); t_close(*sock); goto badout; /* neither tcp not udp succeeded */ } if (clnt_control(client, CLSET_RETRY_TIMEOUT, (char *) tv) == FALSE) { plog(XLOG_ERROR, "clnt_control CLSET_RETRY_TIMEOUT for udp failed"); clnt_destroy(client); goto badout; /* neither tcp not udp succeeded */ } /* udp succeeded */ dlog("get_mount_client: using udp, port %d", sin.sin_port); return client; badout: /* failed */ if (nc) freenetconfigent(nc); return NULL; }