Mercurial > hg > freeDiameter
diff freeDiameter/cnxctx.c @ 201:1b47afa59358
Also timeout on sends
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Wed, 10 Feb 2010 11:22:42 +0900 |
parents | 3e79fef1031d |
children | 536b1dde8761 |
line wrap: on
line diff
--- a/freeDiameter/cnxctx.c Tue Feb 09 18:30:53 2010 +0900 +++ b/freeDiameter/cnxctx.c Wed Feb 10 11:22:42 2010 +0900 @@ -506,6 +506,7 @@ memset(&tv, 0, sizeof(tv)); tv.tv_sec = 3; /* allow 3 seconds timeout for TLS session cleanup */ CHECK_SYS_DO( setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)), /* best effort only */ ); + CHECK_SYS_DO( setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)), /* Also timeout for sending, to avoid waiting forever */ ); } /* A recv-like function, taking a cnxctx object instead of socket as entry. Only used to filter timeouts error (GNUTLS does not like these...) */ @@ -532,7 +533,22 @@ /* Send */ static ssize_t fd_cnx_s_send(struct cnxctx * conn, void *buffer, size_t length) { - return send(conn->cc_socket, buffer, length, 0); + ssize_t ret = 0; + int timedout = 0; +again: + ret = send(conn->cc_socket, buffer, length, 0); + /* Handle special case of timeout */ + if ((ret < 0) && (errno == EAGAIN)) { + if (!conn->cc_closing) + goto again; /* don't care, just ignore */ + if (!timedout) { + timedout ++; /* allow for one timeout while closing */ + goto again; + } + CHECK_SYS_DO(ret, /* continue */); + } + + return ret; } /* Receiver thread (TCP & noTLS) : incoming message is directly saved into the target queue */ @@ -1235,7 +1251,7 @@ if (conn->cc_tls) { CHECK_GNUTLS_DO( ret = fd_tls_send_handle_error(conn, conn->cc_tls_para.session, buf + sent, len - sent), return ENOTCONN ); } else { - CHECK_SYS( ret = send(conn->cc_socket, buf + sent, len - sent, 0) ); /* better to replace with sendmsg for atomic sending? */ + CHECK_SYS( ret = fd_cnx_s_send(conn, buf + sent, len - sent) ); /* better to replace with sendmsg for atomic sending? */ } sent += ret; } while ( sent < len ); @@ -1271,7 +1287,7 @@ CHECK_FCT( send_simple(conn, buf, len) ); } else { if (!conn->cc_tls) { - CHECK_FCT( fd_sctp_sendstr(conn->cc_socket, conn->cc_sctp_para.next, buf, len) ); + CHECK_FCT( fd_sctp_sendstr(conn->cc_socket, conn->cc_sctp_para.next, buf, len, &conn->cc_closing) ); } else { /* push the record to the appropriate session */ ssize_t ret;