From b26e55be19fb5347671f4db719666b8c3e519a3f Mon Sep 17 00:00:00 2001 From: Nanang Izzuddin Date: Fri, 8 Jan 2010 13:08:05 +0000 Subject: Ticket #1001: - Moved setsockopt(SO_UPDATE_ACCEPT_CONTEXT) from pj_sock_accept() to ioqueue_on_accept_complete(). - Added setsockopt(SO_UPDATE_ACCEPT_CONTEXT) in pj_sock_accept() for new accepted socket when immediate connection is available. - Added pj_sock_getsockname() check in unit test ioq_tcp.c for new accepted socket. git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3051 74dad513-b988-da41-8d7b-12977e46ad98 --- pjlib/src/pj/ioqueue_winnt.c | 38 +++++++++++++++++++++++++------------- pjlib/src/pjlib-test/ioq_tcp.c | 9 +++++++++ 2 files changed, 34 insertions(+), 13 deletions(-) (limited to 'pjlib') diff --git a/pjlib/src/pj/ioqueue_winnt.c b/pjlib/src/pj/ioqueue_winnt.c index 254d6530..22bf0a94 100644 --- a/pjlib/src/pj/ioqueue_winnt.c +++ b/pjlib/src/pj/ioqueue_winnt.c @@ -167,14 +167,27 @@ static void scan_closing_keys(pj_ioqueue_t *ioqueue); /* * Process the socket when the overlapped accept() completed. */ -static void ioqueue_on_accept_complete(ioqueue_accept_rec *accept_overlapped) +static void ioqueue_on_accept_complete(pj_ioqueue_key_t *key, + ioqueue_accept_rec *accept_overlapped) { struct sockaddr *local; struct sockaddr *remote; int locallen, remotelen; + pj_status_t status; PJ_CHECK_STACK(); + /* On WinXP or later, use SO_UPDATE_ACCEPT_CONTEXT so that socket + * addresses can be obtained with getsockname() and getpeername(). + */ + status = setsockopt(accept_overlapped->newsock, SOL_SOCKET, + SO_UPDATE_ACCEPT_CONTEXT, + (char*)&key->hnd, + sizeof(SOCKET)); + /* SO_UPDATE_ACCEPT_CONTEXT is for WinXP or later. + * So ignore the error status. + */ + /* Operation complete immediately. */ if (accept_overlapped->addrlen) { GetAcceptExSockaddrs( accept_overlapped->accept_buf, @@ -706,7 +719,7 @@ static pj_bool_t poll_iocp( HANDLE hIocp, DWORD dwTimeout, #if PJ_HAS_TCP case PJ_IOQUEUE_OP_ACCEPT: /* special case for accept. */ - ioqueue_on_accept_complete((ioqueue_accept_rec*)pOv); + ioqueue_on_accept_complete(key, (ioqueue_accept_rec*)pOv); if (key->cb.on_accept_complete) { ioqueue_accept_rec *accept_rec = (ioqueue_accept_rec*)pOv; pj_status_t status = PJ_SUCCESS; @@ -1211,6 +1224,15 @@ PJ_DEF(pj_status_t) pj_ioqueue_accept( pj_ioqueue_key_t *key, if (local && addrlen) { int status; + /* On WinXP or later, use SO_UPDATE_ACCEPT_CONTEXT so that socket + * addresses can be obtained with getsockname() and getpeername(). + */ + status = setsockopt(sock, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, + (char*)&key->hnd, sizeof(SOCKET)); + /* SO_UPDATE_ACCEPT_CONTEXT is for WinXP or later. + * So ignore the error status. + */ + status = getsockname(sock, local, addrlen); if (status != 0) { DWORD dwError = WSAGetLastError(); @@ -1240,16 +1262,6 @@ PJ_DEF(pj_status_t) pj_ioqueue_accept( pj_ioqueue_key_t *key, if (status != PJ_SUCCESS) return status; - /* On WinXP or later, use SO_UPDATE_ACCEPT_CONTEXT so that socket - * addresses can be obtained with getsockname() and getpeername(). - */ - status = setsockopt(op_key_rec->accept.newsock, SOL_SOCKET, - SO_UPDATE_ACCEPT_CONTEXT, - (char*)&key->hnd, sizeof(SOCKET)); - /* SO_UPDATE_ACCEPT_CONTEXT is for WinXP or later. - * So ignore the error status. - */ - op_key_rec->accept.operation = PJ_IOQUEUE_OP_ACCEPT; op_key_rec->accept.addrlen = addrlen; op_key_rec->accept.local = local; @@ -1265,7 +1277,7 @@ PJ_DEF(pj_status_t) pj_ioqueue_accept( pj_ioqueue_key_t *key, &op_key_rec->accept.overlapped ); if (rc == TRUE) { - ioqueue_on_accept_complete(&op_key_rec->accept); + ioqueue_on_accept_complete(key, &op_key_rec->accept); return PJ_SUCCESS; } else { DWORD dwStatus = WSAGetLastError(); diff --git a/pjlib/src/pjlib-test/ioq_tcp.c b/pjlib/src/pjlib-test/ioq_tcp.c index 64adb2f9..5da5afda 100644 --- a/pjlib/src/pjlib-test/ioq_tcp.c +++ b/pjlib/src/pjlib-test/ioq_tcp.c @@ -97,6 +97,15 @@ static void on_ioqueue_accept(pj_ioqueue_key_t *key, "invalid socket and status is %d", status)); } } else { + pj_sockaddr addr; + int client_addr_len; + + client_addr_len = sizeof(addr); + status = pj_sock_getsockname(sock, &addr, &client_addr_len); + if (status != PJ_SUCCESS) { + app_perror("...ERROR in pj_sock_getsockname()", status); + } + callback_accept_key = key; callback_accept_op = op_key; callback_accept_status = status; -- cgit v1.2.3