// XXX Useless void ep_client_release(ep_client_t *clt) { DEBUG_FUNCTION; if (clt && clt->rpcclt.client) rpcclt_release(&clt->rpcclt); }
int rpcclt_initialize(rpcclt_t * client, const char *host, unsigned long prog, unsigned long vers, unsigned int sendsz, unsigned int recvsz, uint32_t port_num, struct timeval timeout) { int status = -1; struct sockaddr_in server; int one = 1; int port = 0; DEBUG_FUNCTION; if (client->sock >= 0) { /* ** socket reference should be set to -1 at initialization or when released ** if rpcclt_initialize is called with socket not set to -1 we may be loosing ** a socket */ warning("rpcclt_initialize - dest %s:%d - prg 0x%8.8x - socket %d may be lost", host,port_num,(unsigned int)prog,client->sock); } client->client = 0; client->sock = -1; server.sin_family = AF_INET; if (rozofs_host2ip_netw((char*)host, &server.sin_addr.s_addr) != 0) { severe("rozofs_host2ip failed for host : %s, %s", host, strerror(errno)); goto out; } if (port_num == 0) { if ((port = pmap_getport(&server, prog, vers, IPPROTO_TCP)) == 0) { //warning("pmap_getport failed%s", clnt_spcreateerror("")); errno = EPROTO; goto out; } server.sin_port = htons(port); } else { server.sin_port = htons(port_num); } if ((client->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { goto out; } // Allows other sockets to bind() to this port, unless there is an active // listening socket bound to the port already. if (setsockopt (client->sock, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof (int)) < 0) { goto out; } // Set a timeout value for output operations if (setsockopt (client->sock, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, sizeof (timeout)) < 0) { goto out; } // This option specifies what should happen when the socket // of a type that promises reliable delivery still has untransmitted // messages when it is closed struct linger linger; linger.l_onoff = 1; //0 = off (l_linger ignored), nonzero = on linger.l_linger = 0; //0 = discard data, nonzero = wait for data sent if (setsockopt (client->sock, SOL_SOCKET, SO_LINGER, &linger, sizeof (linger)) < 0) { goto out; } // If set, disable the Nagle algorithm. This means that segments are always // sent as soon as possible, even if there is only a small amount of data. if (setsockopt (client->sock, SOL_TCP, TCP_NODELAY, (char *) &one, sizeof (int)) < 0) { goto out; } if ((client->sock < 0) || (connect(client->sock, (struct sockaddr *) &server, sizeof (server)) < 0)) { status = -1; goto out; } if ((client->client = clnttcp_create(&server, prog, vers, &client->sock, sendsz, recvsz)) == NULL) { errno = EPROTO; goto out; } // Set TIMEOUT for this connection clnt_control(client->client, CLSET_TIMEOUT, (char *) &timeout); status = 0; out: if (status != 0) rpcclt_release(client); return status; }