X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=lib%2Fsocket.c;h=152dfb4a44df57528ccc7106348bcf32afb14764;hb=d43a8953f531478fa8bfd9eb60a0de257cd06814;hp=733f1f4768e8a0b41c9a51a0903d73e1d08539c0;hpb=bff8fe460dcf4b25071fff966d86877b30eeec90;p=deb_libnfs.git diff --git a/lib/socket.c b/lib/socket.c index 733f1f4..152dfb4 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -24,9 +24,11 @@ #ifdef WIN32 #include "win32_compat.h" -#else +#endif + +#ifdef HAVE_ARPA_INET_H #include -#endif/*WIN32*/ +#endif #ifdef HAVE_POLL_H #include @@ -44,6 +46,10 @@ #include #endif +#ifdef HAVE_NETINET_TCP_H +#include +#endif + #ifdef HAVE_NETDB_H #include #endif @@ -90,6 +96,26 @@ static void set_nonblocking(int fd) #endif //FIXME } +#ifdef HAVE_NETINET_TCP_H +int set_tcp_sockopt(int sockfd, int optname, int value) +{ + int level; + + #if defined(__FreeBSD__) || defined(__sun) || (defined(__APPLE__) && defined(__MACH__)) + struct protoent *buf; + + if ((buf = getprotobyname("tcp")) != NULL) + level = buf->p_proto; + else + return -1; + #else + level = SOL_TCP; + #endif + + return setsockopt(sockfd, level, optname, (char *)&value, sizeof(value)); +} +#endif + int rpc_get_fd(struct rpc_context *rpc) { assert(rpc->magic == RPC_CONTEXT_MAGIC); @@ -161,8 +187,6 @@ static int rpc_read_from_socket(struct rpc_context *rpc) assert(rpc->magic == RPC_CONTEXT_MAGIC); - assert(rpc->magic == RPC_CONTEXT_MAGIC); - if (ioctl(rpc->fd, FIONREAD, &available) != 0) { rpc_set_error(rpc, "Ioctl FIONREAD returned error : %d. Closing socket.", errno); return -1; @@ -256,14 +280,17 @@ static int rpc_read_from_socket(struct rpc_context *rpc) rpc->inpos += count; if (rpc->inpos == rpc->insize) { - if (rpc_process_pdu(rpc, rpc->inbuf, pdu_size) != 0) { - rpc_set_error(rpc, "Invalid/garbage pdu received from server. Closing socket"); - return -1; - } - free(rpc->inbuf); + char *buf = rpc->inbuf; + rpc->inbuf = NULL; rpc->insize = 0; rpc->inpos = 0; + + if (rpc_process_pdu(rpc, buf, pdu_size) != 0) { + rpc_set_error(rpc, "Invalid/garbage pdu received from server. Closing socket"); + return -1; + } + free(buf); } return 0; @@ -365,6 +392,17 @@ void rpc_unset_autoreconnect(struct rpc_context *rpc) rpc->auto_reconnect = 0; } +void rpc_set_tcp_syncnt(struct rpc_context *rpc, int v) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + rpc->tcp_syncnt = v; +} + +#ifndef TCP_SYNCNT +#define TCP_SYNCNT 7 +#endif + static int rpc_connect_sockaddr_async(struct rpc_context *rpc, struct sockaddr_storage *s) { int socksize; @@ -375,6 +413,11 @@ static int rpc_connect_sockaddr_async(struct rpc_context *rpc, struct sockaddr_s case AF_INET: socksize = sizeof(struct sockaddr_in); rpc->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); +#ifdef HAVE_NETINET_TCP_H + if (rpc->tcp_syncnt != RPC_PARAM_UNDEFINED) { + set_tcp_sockopt(rpc->fd, TCP_SYNCNT, rpc->tcp_syncnt); + } +#endif break; default: rpc_set_error(rpc, "Can not handle AF_FAMILY:%d", s->ss_family);