Esempio n. 1
0
// XXX Useless
void ep_client_release(ep_client_t *clt) {
    DEBUG_FUNCTION;
    if (clt && clt->rpcclt.client)
        rpcclt_release(&clt->rpcclt);
}
Esempio n. 2
0
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;
}