From 1e26f458f4e9c7d6547a613e66c9df94abeb913a Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Mon, 10 Jul 2006 21:35:27 +0000 Subject: Fixed several bugs in WinNT IOCP: (1) accept() does not return correct addresses, (2) handle error condition when accept() returns -1 as the new socket git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@599 74dad513-b988-da41-8d7b-12977e46ad98 --- pjlib/src/pjlib-test/ioq_tcp.c | 292 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 292 insertions(+) (limited to 'pjlib/src/pjlib-test/ioq_tcp.c') diff --git a/pjlib/src/pjlib-test/ioq_tcp.c b/pjlib/src/pjlib-test/ioq_tcp.c index 4a546f03..ef958d77 100644 --- a/pjlib/src/pjlib-test/ioq_tcp.c +++ b/pjlib/src/pjlib-test/ioq_tcp.c @@ -530,6 +530,291 @@ on_error: return status; } + +/* + * Repeated connect/accept on the same listener socket. + */ +static int compliance_test_2(void) +{ + enum { MAX_PAIR = 4, TEST_LOOP = 2 }; + + struct listener + { + pj_sock_t sock; + pj_ioqueue_key_t *key; + pj_sockaddr_in addr; + int addr_len; + } listener; + + struct server + { + pj_sock_t sock; + pj_ioqueue_key_t *key; + pj_sockaddr_in local_addr; + pj_sockaddr_in rem_addr; + int rem_addr_len; + pj_ioqueue_op_key_t accept_op; + } server[MAX_PAIR]; + + struct client + { + pj_sock_t sock; + pj_ioqueue_key_t *key; + } client[MAX_PAIR]; + + pj_pool_t *pool = NULL; + char *send_buf, *recv_buf; + pj_ioqueue_t *ioque = NULL; + int i, bufsize = BUF_MIN_SIZE; + pj_ssize_t status; + int test_loop, pending_op = 0; + pj_timestamp t_elapsed; + pj_str_t s; + pj_status_t rc; + + // Create pool. + pool = pj_pool_create(mem, NULL, POOL_SIZE, 4000, NULL); + + + // Create I/O Queue. + rc = pj_ioqueue_create(pool, PJ_IOQUEUE_MAX_HANDLES, &ioque); + if (rc != PJ_SUCCESS) { + app_perror("...ERROR in pj_ioqueue_create()", rc); + return -10; + } + + + // Allocate buffers for send and receive. + send_buf = (char*)pj_pool_alloc(pool, bufsize); + recv_buf = (char*)pj_pool_alloc(pool, bufsize); + + // Create listener socket + rc = pj_sock_socket(PJ_AF_INET, PJ_SOCK_STREAM, 0, &listener.sock); + if (rc != PJ_SUCCESS) { + app_perror("...error creating socket", rc); + status=-20; goto on_error; + } + + // Bind listener socket. + pj_sockaddr_in_init(&listener.addr, 0, 0); + if ((rc=pj_sock_bind(listener.sock, &listener.addr, sizeof(listener.addr))) != 0 ) { + app_perror("...bind error", rc); + status=-30; goto on_error; + } + + // Get listener address. + listener.addr_len = sizeof(listener.addr); + rc = pj_sock_getsockname(listener.sock, &listener.addr, &listener.addr_len); + if (rc != PJ_SUCCESS) { + app_perror("...ERROR in pj_sock_getsockname()", rc); + status=-40; goto on_error; + } + listener.addr.sin_addr = pj_inet_addr(pj_cstr(&s, "127.0.0.1")); + + + // Register listener socket. + rc = pj_ioqueue_register_sock(pool, ioque, listener.sock, NULL, &test_cb, + &listener.key); + if (rc != PJ_SUCCESS) { + app_perror("...ERROR", rc); + status=-50; goto on_error; + } + + + // Listener socket listen(). + if (pj_sock_listen(listener.sock, 5)) { + app_perror("...ERROR in pj_sock_listen()", rc); + status=-60; goto on_error; + } + + + for (test_loop=0; test_loop < TEST_LOOP; ++test_loop) { + // Client connect and server accept. + for (i=0; i 0) { + if (status > pending_op) { + PJ_LOG(3,(THIS_FILE, + "...error: pj_ioqueue_poll() returned %d " + "(only expecting %d)", + status, pending_op)); + return -110; + } + pending_op -= status; + + if (pending_op == 0) { + status = 0; + } + } + } + + // There's no pending operation. + // When we poll the ioqueue, there must not be events. + if (pending_op == 0) { + pj_time_val timeout = {1, 0}; + status = pj_ioqueue_poll(ioque, &timeout); + if (status != 0) { + status=-120; goto on_error; + } + } + + for (i=0; i