/* osi_NetSend * * Return codes: * 0 = success * non-zero = failure */ int osi_NetSend(osi_socket sop, struct sockaddr_in *to, struct iovec *iovec, int iovcnt, afs_int32 size, int istack) { struct msghdr msg; int code; #ifdef ADAPT_PMTU int sockerr; int esize; while (1) { sockerr=0; esize = sizeof(sockerr); kernel_getsockopt(sop, SOL_SOCKET, SO_ERROR, (char *)&sockerr, &esize); if (sockerr == 0) break; handle_socket_error(sop); } #endif msg.msg_name = to; msg.msg_namelen = sizeof(*to); msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_flags = 0; code = kernel_sendmsg(sop, &msg, (struct kvec *) iovec, iovcnt, size); return (code < 0) ? code : 0; }
int ksocknal_lib_get_conn_tunables (ksock_conn_t *conn, int *txmem, int *rxmem, int *nagle) { struct socket *sock = conn->ksnc_sock; int len; int rc; rc = ksocknal_connsock_addref(conn); if (rc != 0) { LASSERT (conn->ksnc_closing); *txmem = *rxmem = *nagle = 0; return (-ESHUTDOWN); } rc = lnet_sock_getbuf(sock, txmem, rxmem); if (rc == 0) { len = sizeof(*nagle); rc = kernel_getsockopt(sock, SOL_TCP, TCP_NODELAY, (char *)nagle, &len); } ksocknal_connsock_decref(conn); if (rc == 0) *nagle = !*nagle; else *txmem = *rxmem = *nagle = 0; return (rc); }
int osi_NetReceive(osi_socket so, struct sockaddr_in *from, struct iovec *iov, int iovcnt, int *lengthp) { struct msghdr msg; int code; #ifdef ADAPT_PMTU int sockerr; int esize; #endif struct iovec tmpvec[RX_MAXWVECS + 2]; struct socket *sop = (struct socket *)so; if (iovcnt > RX_MAXWVECS + 2) { osi_Panic("Too many (%d) iovecs passed to osi_NetReceive\n", iovcnt); } #ifdef ADAPT_PMTU while (1) { sockerr=0; esize = sizeof(sockerr); kernel_getsockopt(sop, SOL_SOCKET, SO_ERROR, (char *)&sockerr, &esize); if (sockerr == 0) break; handle_socket_error(so); } #endif memcpy(tmpvec, iov, iovcnt * sizeof(struct iovec)); msg.msg_name = from; msg.msg_iov = tmpvec; msg.msg_iovlen = iovcnt; msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_flags = 0; code = kernel_recvmsg(sop, &msg, (struct kvec *)tmpvec, iovcnt, *lengthp, 0); if (code < 0) { afs_try_to_freeze(); /* Clear the error before using the socket again. * Oh joy, Linux has hidden header files as well. It appears we can * simply call again and have it clear itself via sock_error(). */ flush_signals(current); /* We don't want no stinkin' signals. */ rxk_lastSocketError = code; rxk_nSocketErrors++; } else { *lengthp = code; code = 0; } return code; }