[WSD] Update to CM interaction. Added tracking of connections by
authorftillier <ftillier@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 27 Sep 2005 00:03:54 +0000 (00:03 +0000)
committerftillier <ftillier@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 27 Sep 2005 00:03:54 +0000 (00:03 +0000)
source/destination IP/port to guarantee unique connections - an
undocumented requirement for providers.

Signed-off-by: Fab Tillier (ftillier@silverstorm.com)
git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@83 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

ulp/wsd/user/ib_cm.c
ulp/wsd/user/ibsp_duplicate.c
ulp/wsd/user/ibsp_iblow.c
ulp/wsd/user/ibspdll.c
ulp/wsd/user/ibspdll.rc
ulp/wsd/user/ibspproto.h
ulp/wsd/user/ibspstruct.h
ulp/wsd/user/misc.c
ulp/wsd/user/sockinfo.c

index aa4fe7a..c53b710 100644 (file)
@@ -110,30 +110,20 @@ cm_req_callback(
        struct ibsp_socket_info *socket_info =\r
                (struct ibsp_socket_info * __ptr64)p_cm_req_rec->context;\r
        struct listen_incoming *incoming;\r
-       ib_rej_status_t rej_status;\r
        ib_cm_mra_t             mra;\r
 \r
-       CL_ENTER( IBSP_DBG_CM, gdbg_lvl );\r
+       IBSP_ENTER( IBSP_DBG_CM );\r
 \r
        CL_ASSERT( socket_info );\r
-\r
-       if( !p_cm_req_rec->p_req_pdata )\r
-       {\r
-               CL_ERROR( IBSP_DBG_CM, gdbg_lvl, ("No private data in CM REQ\n") );\r
-               rej_status = IB_REJ_INSUF_RESOURCES;\r
-               CL_EXIT_ERROR( IBSP_DBG_CM, gdbg_lvl, ("rejecting\n") );\r
-               ib_reject( p_cm_req_rec->h_cm_req, rej_status );\r
-               return;\r
-       }\r
+       CL_ASSERT( p_cm_req_rec->p_req_pdata );\r
 \r
        incoming = HeapAlloc( g_ibsp.heap, 0, sizeof(struct listen_incoming) );\r
-       if( incoming == NULL )\r
+       if( !incoming )\r
        {\r
                /* Low on memory. */\r
-               CL_ERROR( IBSP_DBG_CM, gdbg_lvl, ("HeapAlloc failed\n") );\r
-               rej_status = IB_REJ_INSUF_RESOURCES;\r
-               CL_EXIT_ERROR( IBSP_DBG_CM, gdbg_lvl, ("rejecting\n") );\r
-               ib_reject( p_cm_req_rec->h_cm_req, rej_status );\r
+               IBSP_ERROR( ("HeapAlloc failed, rejecting\n") );\r
+               ib_reject( p_cm_req_rec->h_cm_req, IB_REJ_INSUF_RESOURCES );\r
+               IBSP_EXIT( IBSP_DBG_CM );\r
                return;\r
        }\r
 \r
@@ -150,13 +140,11 @@ cm_req_callback(
                if( cl_qlist_count( &socket_info->info.listen.list ) >= socket_info->info.listen.backlog )\r
                {\r
                        /* Already too many connection requests are queued */\r
-                       cl_spinlock_release( &socket_info->mutex );\r
-                       CL_ERROR( IBSP_DBG_CM, gdbg_lvl, ("already too many incoming connections\n") );\r
+                       IBSP_TRACE1( IBSP_DBG_CM,\r
+                               ("already too many incoming connections, rejecting\n") );\r
                        HeapFree( g_ibsp.heap, 0, incoming );\r
-                       rej_status = IB_REJ_INSUF_QP;   /* or IB_REJ_INSUF_RESOURCES */\r
-                       CL_EXIT_ERROR( IBSP_DBG_CM, gdbg_lvl, ("rejecting\n") );\r
-                       ib_reject( p_cm_req_rec->h_cm_req, rej_status );\r
-                       return;\r
+                       ib_reject( p_cm_req_rec->h_cm_req, IB_REJ_USER_DEFINED );\r
+                       break;\r
                }\r
 \r
                /* Add to the waiting list */\r
@@ -165,7 +153,7 @@ cm_req_callback(
                /* Send MRA */\r
                mra.mra_length = 0;\r
                mra.p_mra_pdata = NULL;\r
-               mra.svc_timeout = 0x1F;\r
+               mra.svc_timeout = 0x15;\r
                ib_cm_mra( p_cm_req_rec->h_cm_req, &mra );\r
 \r
                ibsp_post_select_event( socket_info, FD_ACCEPT, 0 );\r
@@ -173,68 +161,53 @@ cm_req_callback(
 \r
        case IBSP_DUPLICATING_REMOTE:\r
                {\r
-                       int error;\r
                        int ret;\r
 \r
                        HeapFree( g_ibsp.heap, 0, incoming );\r
 \r
                        wait_cq_drain( socket_info );\r
 \r
-                       ib_destroy_socket( socket_info );\r
+                       /* Non-blocking cancel since we're in CM callback context */\r
+                       ib_cm_cancel( socket_info->info.listen.handle, NULL );\r
+                       socket_info->info.listen.handle = NULL;\r
 \r
 #if 0\r
                        cl_spinlock_release( &socket_info->mutex );\r
-                       rej_status = IB_REJ_USER_DEFINED;\r
                        CL_EXIT_ERROR( IBSP_DBG_CM, gdbg_lvl, ("rejecting\n") );\r
-                       ib_reject( p_cm_req_rec->h_cm_req, rej_status );\r
+                       ib_reject( p_cm_req_rec->h_cm_req, IB_REJ_USER_DEFINED );\r
                        ibsp_dup_overlap_abort( socket_info );\r
                        return;\r
 #endif\r
 \r
-                       ret = ib_create_socket( socket_info );\r
-                       if( ret )\r
-                       {\r
-                               cl_spinlock_release( &socket_info->mutex );\r
-                               CL_ERROR( IBSP_DBG_CM, gdbg_lvl,\r
-                                       ("accept failed for duplicate socket (%d)\n", ret) );\r
-                               rej_status = IB_REJ_USER_DEFINED;\r
-                               CL_EXIT_ERROR( IBSP_DBG_CM, gdbg_lvl, ("rejecting\n") );\r
-                               ib_reject( p_cm_req_rec->h_cm_req, rej_status );\r
-                               ibsp_dup_overlap_abort( socket_info );\r
-                               return;\r
-                       }\r
 \r
-                       ret = ib_accept( socket_info, p_cm_req_rec, &error );\r
+                       ret = ib_accept( socket_info, p_cm_req_rec );\r
                        if( ret )\r
                        {\r
                                cl_spinlock_release( &socket_info->mutex );\r
-                               CL_ERROR( IBSP_DBG_CM, gdbg_lvl,\r
-                                       ("accept failed for duplicate socket (%d, %d)\n", ret, error) );\r
-                               rej_status = IB_REJ_USER_DEFINED;\r
+                               IBSP_ERROR(\r
+                                       ("ib_accept for duplicate socket returned %d, rejecting\n",\r
+                                       ret) );\r
                                /* Call ib_destroy_socket for above ib_create_socket() call */\r
                                ib_destroy_socket( socket_info );\r
-                               CL_EXIT_ERROR( IBSP_DBG_CM, gdbg_lvl, ("rejecting\n") );\r
-                               ib_reject( p_cm_req_rec->h_cm_req, rej_status );\r
+                               ib_reject( p_cm_req_rec->h_cm_req, IB_REJ_USER_DEFINED );\r
                                ibsp_dup_overlap_abort( socket_info );\r
+                               IBSP_EXIT( IBSP_DBG_CM );\r
                                return;\r
-\r
                        }\r
                }\r
                break;\r
 \r
        default:\r
-               cl_spinlock_release( &socket_info->mutex );\r
-               CL_ERROR( IBSP_DBG_CM, gdbg_lvl, ("socket is not listening anymore\n") );\r
+               IBSP_ERROR( ("socket is not listening anymore\n") );\r
                HeapFree( g_ibsp.heap, 0, incoming );\r
-               rej_status = IB_REJ_INSUF_QP;   /* or IB_REJ_INSUF_RESOURCES */\r
-               CL_EXIT_ERROR( IBSP_DBG_CM, gdbg_lvl, ("rejecting\n") );\r
-               ib_reject( p_cm_req_rec->h_cm_req, rej_status );\r
-               return;\r
+               /* We're closing down - let some other listen match. */\r
+               ib_reject( p_cm_req_rec->h_cm_req, IB_REJ_INVALID_SID );\r
+               break;\r
        }\r
 \r
        cl_spinlock_release( &socket_info->mutex );\r
 \r
-       CL_EXIT( IBSP_DBG_CM, gdbg_lvl );\r
+       IBSP_EXIT( IBSP_DBG_CM );\r
 }\r
 \r
 \r
@@ -424,7 +397,7 @@ cm_rtu_callback(
 \r
        cl_spinlock_release( &socket_info->mutex );\r
 \r
-       CL_EXIT( IBSP_DBG_CM, gdbg_lvl );\r
+       IBSP_EXIT( IBSP_DBG_CM );\r
 }\r
 \r
 \r
@@ -439,27 +412,32 @@ cm_rej_callback(
        struct ibsp_socket_info *socket_info =\r
                (struct ibsp_socket_info * __ptr64)p_cm_rej_rec->qp_context;\r
 \r
-       CL_ENTER( IBSP_DBG_CM, gdbg_lvl );\r
-\r
-       fzprint(("%s():%d:0x%x:0x%x: socket=0x%p \n", __FUNCTION__,\r
-                        __LINE__, GetCurrentProcessId(), GetCurrentThreadId(), socket_info));\r
+       IBSP_ENTER( IBSP_DBG_CM );\r
 \r
-       CL_TRACE( IBSP_DBG_CONN, gdbg_lvl, ("connect reject, reason=%d\n",\r
-                                                                          p_cm_rej_rec->rej_status));\r
+       IBSP_TRACE( IBSP_DBG_CONN, ("socket %p connect reject, reason=%d\n",\r
+               socket_info, cl_ntoh16(p_cm_rej_rec->rej_status)) );\r
 \r
        cl_spinlock_acquire( &socket_info->mutex );\r
 \r
        switch( socket_info->socket_state )\r
        {\r
        case IBSP_CONNECT:\r
+               /* Remove from connection map. */\r
+               ibsp_conn_remove( socket_info );\r
+\r
                IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_BIND );\r
-               ibsp_post_select_event( socket_info, FD_CONNECT, WSAECONNREFUSED );\r
+               if( p_cm_rej_rec->rej_status == IB_REJ_TIMEOUT )\r
+                       ibsp_post_select_event( socket_info, FD_CONNECT, WSAETIMEDOUT );\r
+               else\r
+                       ibsp_post_select_event( socket_info, FD_CONNECT, WSAECONNREFUSED );\r
                break;\r
 \r
        case IBSP_ACCEPT:\r
+               /* Remove from connection map. */\r
+               ibsp_conn_remove( socket_info );\r
+\r
                IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_BIND );\r
-               SetEvent( socket_info->info.accept.event );\r
-               break;\r
+               /* Fall through. */\r
 \r
        case IBSP_DUPLICATING_NEW:\r
                /* Leave in that state. IBSPSocket will eventually return \r
@@ -468,13 +446,15 @@ cm_rej_callback(
                break;\r
 \r
        default:\r
-               CL_ERROR( IBSP_DBG_CM, gdbg_lvl, ("Got an unexpected REJ\n") );\r
+               IBSP_ERROR( ("socket %p got an REJ reason %d in state %s\n",\r
+                       socket_info, cl_ntoh16( p_cm_rej_rec->rej_status ),\r
+                       IBSP_SOCKET_STATE_STR(socket_info->socket_state)) );\r
                break;\r
        }\r
 \r
        cl_spinlock_release( &socket_info->mutex );\r
 \r
-       CL_EXIT( IBSP_DBG_CM, gdbg_lvl );\r
+       IBSP_EXIT( IBSP_DBG_CM );\r
 }\r
 \r
 \r
@@ -509,70 +489,62 @@ cm_dreq_callback(
        struct ibsp_socket_info *socket_info =\r
                (struct ibsp_socket_info * __ptr64)p_cm_dreq_rec->qp_context;\r
 \r
-       CL_ENTER( IBSP_DBG_CM, gdbg_lvl );\r
-       CL_TRACE( IBSP_DBG_CM, gdbg_lvl,\r
-               ("cm_dreq_callback: enter, socket_state=%s, socket=%p\n",\r
-               IBSP_SOCKET_STATE_STR( socket_info->socket_state ), socket_info) );\r
+       IBSP_ENTER( IBSP_DBG_CM );\r
+       IBSP_TRACE1( IBSP_DBG_CM,\r
+               ("socket=%p state=%s\n",\r
+               socket_info, IBSP_SOCKET_STATE_STR( socket_info->socket_state )) );\r
 \r
        reason = (struct disconnect_reason * __ptr64)p_cm_dreq_rec->p_dreq_pdata;\r
 \r
-       if( reason->type == DISC_DUPLICATING )\r
-       {\r
-               cl_spinlock_acquire( &socket_info->mutex );\r
+       cl_spinlock_acquire( &socket_info->mutex );\r
 \r
-               if( socket_info->socket_state == IBSP_CONNECTED )\r
+       if( socket_info->socket_state == IBSP_CONNECTED )\r
+       {\r
+               switch( reason->type )\r
                {\r
-                       int ret;\r
-                       int error;\r
-\r
-                       IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_DUPLICATING_REMOTE );\r
-                       socket_info->qp_error = -1;\r
-                       socket_info->duplicate.identifier = reason->duplicating.identifier;\r
-                       socket_info->duplicate.dwProcessId = reason->duplicating.dwProcessId;\r
-\r
-                       /* Now, setup our listening callback. */\r
-                       socket_info->info.listen.listen_req_param.dwProcessId =\r
-                               reason->duplicating.dwProcessId;\r
-                       socket_info->info.listen.listen_req_param.identifier =\r
-                               reason->duplicating.identifier;\r
-\r
-                       ret = ib_listen( socket_info, &error );\r
-                       if( ret )\r
+               case DISC_DUPLICATING:\r
                        {\r
-                               CL_EXIT_ERROR( IBSP_DBG_CONN, gdbg_lvl,\r
-                                       ("ib_listen failed with %d\n", error) );\r
-                               IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_DISCONNECTED );\r
-                               socket_info->qp_error = WSAECONNRESET;\r
+                               int ret;\r
+                               int error;\r
+\r
+                               IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_DUPLICATING_REMOTE );\r
+                               socket_info->qp_error = -1;\r
+                               socket_info->duplicate.identifier = reason->duplicating.identifier;\r
+                               socket_info->duplicate.dwProcessId = reason->duplicating.dwProcessId;\r
+\r
+                               /* Now, setup our listening callback. */\r
+                               socket_info->info.listen.listen_req_param.dwProcessId =\r
+                                       reason->duplicating.dwProcessId;\r
+                               socket_info->info.listen.listen_req_param.identifier =\r
+                                       reason->duplicating.identifier;\r
+\r
+                               ret = ib_listen( socket_info, &error );\r
+                               if( !ret )\r
+                                       break;\r
+\r
+                               IBSP_ERROR_EXIT( ("ib_listen failed with %d\n", error) );\r
+                               /* Fall through. */\r
                        }\r
+               default:\r
+                       /* Right now, treat anything as a normal disconnect. */\r
+                       IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_DISCONNECTED );\r
+                       /* We changed the state - remove from connection map. */\r
+                       ibsp_conn_remove( socket_info );\r
+                       socket_info->qp_error = WSAECONNRESET;\r
                }\r
-\r
-               cl_spinlock_release( &socket_info->mutex );\r
        }\r
        else\r
        {\r
-               /* Right now, treat anything as a normal disconnect. */\r
-               cl_spinlock_acquire( &socket_info->mutex );\r
-\r
-               if( socket_info->socket_state == IBSP_CONNECTED )\r
-               {\r
-                       IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_DISCONNECTED );\r
-                       socket_info->qp_error = WSAECONNRESET;\r
-               }\r
-\r
-               cl_spinlock_release( &socket_info->mutex );\r
        }\r
+       cl_spinlock_release( &socket_info->mutex );\r
 \r
        memset( &cm_drep, 0, sizeof(cm_drep) );\r
 \r
        status = ib_cm_drep( p_cm_dreq_rec->h_cm_dreq, &cm_drep );\r
        if( status != IB_SUCCESS )\r
-       {\r
-               CL_ERROR( IBSP_DBG_CM, gdbg_lvl, ("ib_cm_drep failed (0x%d)\n", status) );\r
-       }\r
-\r
-       SetEvent( socket_info->info.disconnect.event );\r
+               IBSP_ERROR( ("ib_cm_drep returned %s\n", ib_get_err_str( status )) );\r
 \r
-       CL_EXIT( IBSP_DBG_CM, gdbg_lvl );\r
+       IBSP_EXIT( IBSP_DBG_CM );\r
 }\r
 \r
 \r
@@ -584,15 +556,8 @@ static void AL_API
 cm_drep_callback(\r
        IN                              ib_cm_drep_rec_t                        *p_cm_drep_rec )\r
 {\r
-       struct ibsp_socket_info *socket_info =\r
-               (struct ibsp_socket_info * __ptr64)p_cm_drep_rec->qp_context;\r
-\r
        CL_ENTER( IBSP_DBG_CM, gdbg_lvl );\r
-\r
-       CL_TRACE( IBSP_DBG_CM, gdbg_lvl, ("posting DREP event from drep_callback\n") );\r
-\r
-       SetEvent( socket_info->info.disconnect.event );\r
-\r
+       UNUSED_PARAM( p_cm_drep_rec );\r
        CL_EXIT( IBSP_DBG_CM, gdbg_lvl );\r
 }\r
 \r
@@ -726,30 +691,27 @@ ib_listen(
 \r
 \r
 /* Reject all the queued incoming connection requests. */\r
-static void\r
-empty_listen_queue(\r
-       IN                              struct ibsp_socket_info         *socket_info )\r
+void\r
+ib_listen_backlog(\r
+       IN                              struct ibsp_socket_info         *socket_info,\r
+       IN                              int                                                     backlog )\r
 {\r
        cl_list_item_t *item;\r
        struct listen_incoming *incoming;\r
 \r
-       // TODO: we don't need to lock anymore, do we?\r
-       cl_spinlock_acquire( &socket_info->mutex );\r
+       socket_info->info.listen.backlog = backlog;\r
 \r
-       for( item = cl_qlist_head( &socket_info->info.listen.list );\r
-               item != cl_qlist_end( &socket_info->info.listen.list );\r
-               item = cl_qlist_head( &socket_info->info.listen.list ) )\r
+       while(\r
+               cl_qlist_count( &socket_info->info.listen.list ) > (uint32_t)backlog )\r
        {\r
-               incoming = PARENT_STRUCT(item, struct listen_incoming, item);\r
+               item = cl_qlist_remove_tail( &socket_info->info.listen.list );\r
 \r
-               cl_qlist_remove_item( &socket_info->info.listen.list, &incoming->item );\r
+               incoming = PARENT_STRUCT(item, struct listen_incoming, item);\r
 \r
                ib_reject( incoming->cm_req_received.h_cm_req, IB_REJ_USER_DEFINED );\r
 \r
                HeapFree( g_ibsp.heap, 0, incoming );\r
        }\r
-\r
-       cl_spinlock_release( &socket_info->mutex );\r
 }\r
 \r
 \r
@@ -760,7 +722,7 @@ ib_listen_cancel(
 {\r
        ib_api_status_t status;\r
 \r
-       CL_ENTER( IBSP_DBG_CM, gdbg_lvl );\r
+       IBSP_ENTER( IBSP_DBG_CM );\r
 \r
        /* We should be in the CLOSING state */\r
        CL_ASSERT( socket_info->socket_state == IBSP_CLOSING );\r
@@ -778,29 +740,41 @@ ib_listen_cancel(
 \r
        /* We can empty the queue now. Since we are closing, \r
         * no new entry will be added. */\r
-       empty_listen_queue( socket_info );\r
+       cl_spinlock_acquire( &socket_info->mutex );\r
+       ib_listen_backlog( socket_info, 0 );\r
+       cl_spinlock_release( &socket_info->mutex );\r
 \r
        socket_info->info.listen.handle = NULL;\r
 \r
-       CL_EXIT( IBSP_DBG_CM, gdbg_lvl );\r
+       IBSP_EXIT( IBSP_DBG_CM );\r
 }\r
 \r
 \r
 int\r
 ib_connect(\r
        IN                              struct ibsp_socket_info         *socket_info,\r
-       IN                              ib_path_rec_t                           *path_rec,\r
-               OUT                     LPINT                                           lpErrno )\r
+       IN                              ib_path_rec_t                           *path_rec )\r
 {\r
        ib_cm_req_t cm_req;\r
        ib_api_status_t status;\r
        struct cm_req_params params;\r
 \r
-       CL_ENTER( IBSP_DBG_CM, gdbg_lvl );\r
+       IBSP_ENTER( IBSP_DBG_CM );\r
 \r
        fzprint(("%s():%d:0x%x:0x%x: socket=0x%p \n", __FUNCTION__,\r
                         __LINE__, GetCurrentProcessId(), GetCurrentThreadId(), socket_info));\r
 \r
+       CL_TRACE( IBSP_DBG_CM, gdbg_lvl, ("From:\n") );\r
+       DebugPrintSockAddr( IBSP_DBG_CM, gdbg_lvl, &socket_info->local_addr );\r
+       CL_TRACE( IBSP_DBG_CM, gdbg_lvl, ("To:\n") );\r
+       DebugPrintSockAddr( IBSP_DBG_CM, gdbg_lvl, &socket_info->peer_addr );\r
+\r
+       /* Insert into the connection map. */\r
+       if( !ibsp_conn_insert( socket_info ) )\r
+       {\r
+               IBSP_EXIT( IBSP_DBG_CM );\r
+               return WSAEADDRINUSE;\r
+       }\r
 \r
        memset( &cm_req, 0, sizeof(cm_req) );\r
 \r
@@ -821,10 +795,6 @@ ib_connect(
        CL_TRACE( IBSP_DBG_CM, gdbg_lvl,\r
                ("connecting to port %d, SID=%016I64x\n", socket_info->peer_addr.sin_port,\r
                cm_req.svc_id) );\r
-       CL_TRACE( IBSP_DBG_CM, gdbg_lvl, ("From:\n") );\r
-       DebugPrintSockAddr( IBSP_DBG_CM, gdbg_lvl, &socket_info->local_addr );\r
-       CL_TRACE( IBSP_DBG_CM, gdbg_lvl, ("To:\n") );\r
-       DebugPrintSockAddr( IBSP_DBG_CM, gdbg_lvl, &socket_info->peer_addr );\r
 \r
        cm_req.req_length = sizeof(struct cm_req_params);\r
 \r
@@ -859,17 +829,19 @@ ib_connect(
        status = ib_cm_req( &cm_req );\r
        if( status != IB_SUCCESS )\r
        {\r
-               CL_EXIT_ERROR( IBSP_DBG_CM, gdbg_lvl, ("ib_cm_req failed (0x%d)\n", status) );\r
-               *lpErrno = ibal_to_wsa_error( status );\r
-               return SOCKET_ERROR;\r
-       }\r
+               /* Remove from connection map. */\r
+               ibsp_conn_remove( socket_info );\r
 \r
-       CL_EXIT( IBSP_DBG_CM, gdbg_lvl );\r
+               IBSP_ERROR_EXIT( ("ib_cm_req failed (0x%d)\n", status) );\r
+               return WSAEHOSTUNREACH;\r
+       }\r
 \r
-       *lpErrno = 0;\r
-       return 0;\r
+       IBSP_EXIT( IBSP_DBG_CM );\r
+       /* Operation is pending */\r
+       return WSAEWOULDBLOCK;\r
 }\r
 \r
+\r
 void\r
 ib_reject(\r
        IN                              const ib_cm_handle_t            h_cm,\r
@@ -878,32 +850,35 @@ ib_reject(
        ib_cm_rej_t cm_rej;\r
        ib_api_status_t status;\r
 \r
-       CL_ENTER( IBSP_DBG_CM, gdbg_lvl );\r
-\r
-       UNUSED_PARAM( rej_status );\r
+       IBSP_ENTER( IBSP_DBG_CM );\r
 \r
        memset( &cm_rej, 0, sizeof(cm_rej) );\r
+       cm_rej.rej_status = rej_status;\r
 \r
        status = ib_cm_rej( h_cm, &cm_rej );\r
        if( status != IB_SUCCESS )\r
-       {\r
-               CL_ERROR( IBSP_DBG_CM, gdbg_lvl, ("ib_cm_rej failed (0x%d)\n", status) );\r
-       }\r
+               IBSP_ERROR( ("ib_cm_rej returned %s\n", ib_get_err_str( status )) );\r
 \r
-       CL_EXIT( IBSP_DBG_CM, gdbg_lvl );\r
+       IBSP_EXIT( IBSP_DBG_CM );\r
 }\r
 \r
 \r
 int\r
 ib_accept(\r
        IN                              struct ibsp_socket_info         *socket_info,\r
-       IN                              ib_cm_req_rec_t                         *cm_req_received,\r
-               OUT                     LPINT                                           lpErrno )\r
+       IN                              ib_cm_req_rec_t                         *cm_req_received )\r
 {\r
        ib_cm_rep_t cm_rep;\r
        ib_api_status_t status;\r
 \r
-       CL_ENTER( IBSP_DBG_CM, gdbg_lvl );\r
+       IBSP_ENTER( IBSP_DBG_CM );\r
+\r
+       /* Insert into the connection map. */\r
+       if( !ibsp_conn_insert( socket_info ) )\r
+       {\r
+               IBSP_EXIT( IBSP_DBG_CM );\r
+               return WSAEADDRINUSE;\r
+       }\r
 \r
        memset( &cm_rep, 0, sizeof(cm_rep) );\r
 \r
@@ -934,14 +909,16 @@ ib_accept(
        status = ib_cm_rep( cm_req_received->h_cm_req, &cm_rep );\r
        if( status != IB_SUCCESS )\r
        {\r
-               CL_EXIT_ERROR( IBSP_DBG_CM, gdbg_lvl, ("ib_cm_rep failed (0x%d)\n", status) );\r
-               *lpErrno = ibal_to_wsa_error( status );\r
-               return SOCKET_ERROR;\r
-       }\r
+               /* Remove from connection map. */\r
+               ibsp_conn_remove( socket_info );\r
 \r
-       CL_EXIT( IBSP_DBG_CM, gdbg_lvl );\r
+               IBSP_ERROR_EXIT(\r
+                       ("ib_cm_rep failed (0x%d) at time %I64d\n",\r
+                       ib_get_err_str( status ), cl_get_time_stamp()) );\r
+               return WSAEACCES;\r
+       }\r
 \r
-       *lpErrno = 0;\r
+       IBSP_EXIT( IBSP_DBG_CM );\r
        return 0;\r
 }\r
 \r
@@ -953,11 +930,9 @@ ib_disconnect(
 {\r
        ib_api_status_t         status;\r
        ib_cm_dreq_t            cm_dreq;\r
-       ib_qp_attr_t            qp_attr;\r
+       ib_qp_mod_t                     qp_mod;\r
 \r
-       CL_ENTER( IBSP_DBG_CM, gdbg_lvl );\r
-\r
-       socket_info->info.disconnect.event = CreateEvent( NULL, FALSE, FALSE, NULL );\r
+       IBSP_ENTER( IBSP_DBG_CM );\r
 \r
        memset( &cm_dreq, 0, sizeof(cm_dreq) );\r
 \r
@@ -970,47 +945,32 @@ ib_disconnect(
 \r
        status = ib_cm_dreq( &cm_dreq );\r
 \r
-       if( status != IB_SUCCESS )\r
-       {\r
-               CL_ERROR( IBSP_DBG_CM, gdbg_lvl, ("ib_cm_dreq failed (0x%d)\n", status) );\r
-               goto done;\r
-       }\r
-\r
-       CL_TRACE( IBSP_DBG_CM, gdbg_lvl, ("wait for DREP event\n") );\r
-\r
-       if( WaitForSingleObject( socket_info->info.disconnect.event, INFINITE ) != WAIT_OBJECT_0 )\r
+       /*\r
+        * If both sides initiate disconnection, we might get\r
+        * an invalid state or handle here.\r
+        */\r
+       if( status != IB_SUCCESS && status != IB_INVALID_STATE &&\r
+               status != IB_INVALID_HANDLE )\r
        {\r
-               CL_ERROR( IBSP_DBG_CM, gdbg_lvl, ("WaitForSingleObject failed\n") );\r
+               IBSP_ERROR( ("ib_cm_dreq returned %s\n", ib_get_err_str( status )) );\r
        }\r
 \r
-       memset( &qp_attr, 0, sizeof(qp_attr) );\r
-       status = ib_query_qp( socket_info->qp, &qp_attr );\r
+       /*\r
+        * Note that we don't care about getting the DREP - we move the QP to the\r
+        * error state now and flush all posted work requests.  If the\r
+        * disconnection was graceful, we'll only have the pre-posted receives to\r
+        * flush.  If the disconnection is ungraceful, we don't care if we\r
+        * interrupt transfers.\r
+        */\r
+\r
+       /* Force the QP to error state to flush posted receives. */\r
+       memset( &qp_mod, 0, sizeof(qp_mod) );\r
+       qp_mod.req_state = IB_QPS_ERROR;\r
+       status = ib_modify_qp( socket_info->qp, &qp_mod );\r
        if( status != IB_SUCCESS )\r
        {\r
-               CL_ERROR( IBSP_DBG_EP, gdbg_lvl, ("ib_query_qp failed (%d)\n", status));\r
-               goto done;\r
+               socket_info->send_cnt = 0;\r
+               socket_info->recv_cnt = 0;\r
        }\r
-\r
-       if( qp_attr.state != IB_QPS_ERROR )\r
-       {\r
-               ib_qp_mod_t qp_mod;\r
-\r
-               fzprint(("%s():%d:0x%x:0x%x: socket=0x%p qp state=%d\n", __FUNCTION__,\r
-                                       __LINE__, GetCurrentProcessId(),\r
-                                       GetCurrentThreadId(), socket_info, qp_attr.state));\r
-               memset( &qp_mod, 0, sizeof(qp_mod) );\r
-               qp_mod.req_state = IB_QPS_ERROR;\r
-               ib_modify_qp( socket_info->qp, &qp_mod );\r
-               if( status != IB_SUCCESS )\r
-               {\r
-                       CL_ERROR( IBSP_DBG_CM, gdbg_lvl,\r
-                               ("ib_mod_qp failed (0x%d)\n", status) );\r
-               }\r
-               Sleep( 100 );\r
-       }\r
-\r
-done:\r
-       CloseHandle( socket_info->info.disconnect.event );\r
-\r
-       CL_EXIT( IBSP_DBG_CM, gdbg_lvl );\r
+       IBSP_EXIT( IBSP_DBG_CM );\r
 }\r
index 9e13bf9..b5e3dbd 100644 (file)
@@ -61,7 +61,6 @@ setup_duplicate_socket(
        struct ibsp_duplicate_info *dup_info;\r
        ib_net64_t dest_port_guid;\r
        ib_path_rec_t path_rec;\r
-       int error;\r
 \r
        CL_ASSERT( socket_info->socket_state == IBSP_CREATE );\r
 \r
@@ -186,8 +185,8 @@ setup_duplicate_socket(
        socket_info->info.connect.event = CreateEvent( NULL, FALSE, FALSE, NULL );\r
 \r
        /* Connects the QP. */\r
-       ret = ib_connect( socket_info, &path_rec, &error );\r
-       if( ret )\r
+       ret = ib_connect( socket_info, &path_rec );\r
+       if( ret != WSAEWOULDBLOCK )\r
        {\r
                CL_ERROR( IBSP_DBG_CONN, gdbg_lvl, ("ib_connect failed (%d)\n", ret) );\r
                goto done;\r
@@ -210,7 +209,7 @@ setup_duplicate_socket(
 \r
        ret = 0;\r
 \r
-  done:\r
+done:\r
        if( h )\r
                CloseHandle( h );\r
 \r
@@ -226,7 +225,10 @@ setup_duplicate_socket(
 }\r
 \r
 \r
-/* This function is called by the previous controlling process. */\r
+/*\r
+ * This function is called by the previous controlling process.\r
+ * Called with the socket_info->mutex held.\r
+ */\r
 int\r
 prepare_duplicate_socket(\r
        IN                              struct ibsp_socket_info         *socket_info,\r
@@ -245,6 +247,9 @@ prepare_duplicate_socket(
        CL_ASSERT( socket_info->socket_state == IBSP_CONNECTED );\r
        IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_DUPLICATING_OLD );\r
 \r
+       /* We changed the state - remove from connection map. */\r
+       ibsp_conn_remove( socket_info );\r
+\r
        /* We might have a left-over from the previous duplicate. */\r
        if( socket_info->duplicate.mmap_handle != NULL )\r
        {\r
@@ -325,7 +330,9 @@ prepare_duplicate_socket(
        reason.duplicating.identifier = identifier;\r
        reason.duplicating.dwProcessId = dwProcessId;\r
 \r
+       cl_spinlock_release( &socket_info->mutex );\r
        ib_disconnect( socket_info, &reason );\r
+       cl_spinlock_acquire( &socket_info->mutex );\r
 \r
        wait_cq_drain( socket_info );\r
 \r
index 4907327..ab14d89 100644 (file)
@@ -145,7 +145,6 @@ complete_wq(
 \r
                /* Override the length, as per the WSD specs. */\r
                wr->lpOverlapped->InternalHigh = 0;\r
-               socket_info->qp_error = WSAECONNABORTED;\r
                break;\r
 \r
        case IB_WCS_LOCAL_LEN_ERR:\r
@@ -593,7 +592,6 @@ ib_destroy_cq_tinfo(
                                free_wclist, done_wclist) );\r
                }\r
 \r
-\r
                CL_TRACE( IBSP_DBG_WQ, gdbg_lvl, ("%s():%d:0x%x:0x%x: ib_destroy_cq() start..\n",\r
                        __FUNCTION__,\r
                        __LINE__, GetCurrentProcessId(),\r
@@ -1330,3 +1328,67 @@ shutdown_and_destroy_socket_info(
 \r
        CL_EXIT( IBSP_DBG_EP, gdbg_lvl );\r
 }\r
+\r
+\r
+boolean_t\r
+ibsp_conn_insert(\r
+       IN                              struct ibsp_socket_info         *s )\r
+{\r
+       struct ibsp_socket_info         *p_sock;\r
+       cl_rbmap_item_t                         *p_item, *p_insert_at;\r
+       boolean_t                                       left = TRUE;\r
+\r
+       p_item = cl_rbmap_root( &g_ibsp.conn_map );\r
+       p_insert_at = p_item;\r
+\r
+       cl_spinlock_acquire( &g_ibsp.socket_info_mutex );\r
+       CL_ASSERT( !s->conn_item.p_map );\r
+       while( p_item != cl_rbmap_end( &g_ibsp.conn_map ) )\r
+       {\r
+               p_insert_at = p_item;\r
+               p_sock = PARENT_STRUCT( p_item, struct ibsp_socket_info, conn_item );\r
+               if( p_sock->local_addr.sin_family < s->local_addr.sin_family )\r
+                       p_item = cl_rbmap_left( p_item ), left = TRUE;\r
+               else if( p_sock->local_addr.sin_family > s->local_addr.sin_family )\r
+                       p_item = cl_rbmap_right( p_item ), left = FALSE;\r
+               else if( p_sock->local_addr.sin_addr.S_un.S_addr < s->local_addr.sin_addr.S_un.S_addr )\r
+                       p_item = cl_rbmap_left( p_item ), left = TRUE;\r
+               else if( p_sock->local_addr.sin_addr.S_un.S_addr > s->local_addr.sin_addr.S_un.S_addr )\r
+                       p_item = cl_rbmap_right( p_item ), left = FALSE;\r
+               else if( p_sock->local_addr.sin_port < s->local_addr.sin_port )\r
+                       p_item = cl_rbmap_left( p_item ), left = TRUE;\r
+               else if( p_sock->local_addr.sin_port > s->local_addr.sin_port )\r
+                       p_item = cl_rbmap_right( p_item ), left = FALSE;\r
+               else if( p_sock->peer_addr.sin_family < s->peer_addr.sin_family )\r
+                       p_item = cl_rbmap_left( p_item ), left = TRUE;\r
+               else if( p_sock->peer_addr.sin_family > s->peer_addr.sin_family )\r
+                       p_item = cl_rbmap_right( p_item ), left = FALSE;\r
+               else if( p_sock->peer_addr.sin_addr.S_un.S_addr < s->peer_addr.sin_addr.S_un.S_addr )\r
+                       p_item = cl_rbmap_left( p_item ), left = TRUE;\r
+               else if( p_sock->peer_addr.sin_addr.S_un.S_addr > s->peer_addr.sin_addr.S_un.S_addr )\r
+                       p_item = cl_rbmap_right( p_item ), left = FALSE;\r
+               else if( p_sock->peer_addr.sin_port < s->peer_addr.sin_port )\r
+                       p_item = cl_rbmap_left( p_item ), left = TRUE;\r
+               else if( p_sock->peer_addr.sin_port > s->peer_addr.sin_port )\r
+                       p_item = cl_rbmap_right( p_item ), left = FALSE;\r
+               else\r
+                       goto done;\r
+       }\r
+\r
+       cl_rbmap_insert( &g_ibsp.conn_map, p_insert_at, &s->conn_item, left );\r
+\r
+done:\r
+       cl_spinlock_release( &g_ibsp.socket_info_mutex );\r
+       return p_item == cl_rbmap_end( &g_ibsp.conn_map );\r
+}\r
+\r
+\r
+void\r
+ibsp_conn_remove(\r
+       IN                              struct ibsp_socket_info         *s )\r
+{\r
+       cl_spinlock_acquire( &g_ibsp.socket_info_mutex );\r
+       CL_ASSERT( s->conn_item.p_map );\r
+       cl_rbmap_remove_item( &g_ibsp.conn_map, &s->conn_item );\r
+       cl_spinlock_release( &g_ibsp.socket_info_mutex );\r
+}\r
index 8b7bbff..1d6c9bd 100644 (file)
@@ -466,8 +466,7 @@ reject:
        /* Update the state of the socket context */\r
        IBSP_CHANGE_SOCKET_STATE( new_socket_info, IBSP_ACCEPT );\r
 \r
-       ret = ib_accept( new_socket_info, &incoming->cm_req_received, lpErrno );\r
-\r
+       ret = ib_accept( new_socket_info, &incoming->cm_req_received );\r
        if( ret )\r
        {\r
                IBSP_CHANGE_SOCKET_STATE( new_socket_info, IBSP_CREATE );\r
@@ -770,7 +769,7 @@ IBSPConnect(
        ib_net64_t dest_port_guid;\r
        ib_path_rec_t path_rec;\r
 \r
-       CL_EXIT( IBSP_DBG_CONN, gdbg_lvl );\r
+       IBSP_ENTER( IBSP_DBG_CONN );\r
 \r
        UNUSED_PARAM( lpCalleeData );\r
        UNUSED_PARAM( lpSQOS );\r
@@ -787,59 +786,66 @@ IBSPConnect(
        if( lpCallerData )\r
        {\r
                /* We don't support that. The current switch does not use it. */\r
-               CL_ERROR( IBSP_DBG_CONN, gdbg_lvl, ("lpCallerData.len=%d\n", lpCallerData->len) );\r
+               IBSP_ERROR_EXIT( ("lpCallerData.len=%d\n", lpCallerData->len) );\r
                *lpErrno = WSAEINVAL;\r
-               goto error;\r
+               return SOCKET_ERROR;\r
        }\r
 \r
        if( namelen < sizeof(struct sockaddr_in) )\r
        {\r
-               CL_ERROR( IBSP_DBG_CONN, gdbg_lvl,\r
+               IBSP_ERROR_EXIT(\r
                        ("invalid remote address (%d)\n", socket_info->socket_state) );\r
                *lpErrno = WSAEFAULT;\r
-               goto error;\r
+               return SOCKET_ERROR;\r
        }\r
 \r
        /* Check if the name (actually address) of peer entity is correct */\r
        if( addr->sin_family != AF_INET ||\r
                addr->sin_port == 0 || addr->sin_addr.s_addr == INADDR_ANY )\r
        {\r
-               CL_ERROR( IBSP_DBG_CONN, gdbg_lvl,\r
+               IBSP_ERROR_EXIT(\r
                        ("peer entity address is invalid (%d, %d, %x)\n",\r
                        addr->sin_family, addr->sin_port, addr->sin_addr.s_addr) );\r
                *lpErrno = WSAEADDRNOTAVAIL;\r
-               goto error;\r
+               return SOCKET_ERROR;\r
        }\r
 \r
        if( socket_info->local_addr.sin_addr.S_un.S_addr == addr->sin_addr.S_un.S_addr )\r
        {\r
                /* Loopback - let the regular stack take care of that. */\r
-               CL_ERROR( IBSP_DBG_CONN, gdbg_lvl, ("Loopback!\n") );\r
+               IBSP_ERROR_EXIT( ("Loopback!\n") );\r
                *lpErrno = WSAEADDRNOTAVAIL;\r
-               goto error;\r
+               return SOCKET_ERROR;\r
        }\r
 \r
        /* Get the GUID for that IP address. */\r
        ret = query_guid_address( socket_info->port, addr->sin_addr.s_addr, &dest_port_guid );\r
        if( ret )\r
        {\r
-               CL_ERROR( IBSP_DBG_CONN, gdbg_lvl,\r
+               IBSP_ERROR_EXIT(\r
                        ("query_guid_address failed for IP %08x\n", addr->sin_addr.s_addr) );\r
                *lpErrno = WSAEADDRNOTAVAIL;\r
-               goto error;\r
+               return SOCKET_ERROR;\r
        }\r
 \r
        CL_TRACE( IBSP_DBG_CONN, gdbg_lvl, ("got GUID %I64x for IP %s\n",\r
                CL_NTOH64( dest_port_guid ), inet_ntoa( addr->sin_addr )) );\r
 \r
+       if( dest_port_guid == socket_info->port->guid )\r
+       {\r
+               IBSP_ERROR_EXIT( ("Loopback!\n") );\r
+               *lpErrno = WSAEADDRNOTAVAIL;\r
+               return SOCKET_ERROR;\r
+       }\r
+\r
        /* Get the path record */\r
        ret = query_pr( socket_info->port, dest_port_guid, &path_rec );\r
        if( ret )\r
        {\r
-               CL_ERROR( IBSP_DBG_CONN, gdbg_lvl,\r
+               IBSP_ERROR_EXIT(\r
                        ("query_pr failed for IP %08x\n", addr->sin_addr.s_addr) );\r
                *lpErrno = WSAEADDRNOTAVAIL;\r
-               goto error;\r
+               return SOCKET_ERROR;\r
        }\r
 \r
        cl_spinlock_acquire( &socket_info->mutex );\r
@@ -852,26 +858,20 @@ IBSPConnect(
                break;\r
 \r
        case IBSP_CONNECTED:\r
-               cl_spinlock_release( &socket_info->mutex );\r
-               CL_ERROR( IBSP_DBG_CONN, gdbg_lvl, ("Socket is already connected\n") );\r
+               IBSP_ERROR( ("Socket is already connected\n") );\r
                *lpErrno = WSAEISCONN;\r
-               goto error;\r
-               break;\r
+               goto done;\r
 \r
        case IBSP_LISTEN:\r
-               cl_spinlock_release( &socket_info->mutex );\r
-               CL_ERROR( IBSP_DBG_CONN, gdbg_lvl, ("Socket is a listening socket\n") );\r
+               IBSP_ERROR( ("Socket is a listening socket\n") );\r
                *lpErrno = WSAEINVAL;\r
-               goto error;\r
+               goto done;\r
 \r
        default:\r
-               cl_spinlock_release( &socket_info->mutex );\r
-               CL_ERROR( IBSP_DBG_CONN, gdbg_lvl,\r
-                       ("Socket is not in the bound state (%s)\n",\r
+               IBSP_ERROR( ("Socket is not in the bound state (%s)\n",\r
                        IBSP_SOCKET_STATE_STR( socket_info->socket_state )) );\r
                *lpErrno = WSAEINVAL;\r
-               goto error;\r
-               break;\r
+               goto done;\r
        }\r
 \r
        /* Store the peer entity's address in socket context */\r
@@ -880,34 +880,20 @@ IBSPConnect(
        /* Update the socket state */\r
        IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_CONNECT );\r
 \r
-       cl_spinlock_release( &socket_info->mutex );\r
-\r
        /* Connect */\r
-       ret = ib_connect( socket_info, &path_rec, lpErrno );\r
-       if( ret )\r
+       *lpErrno = ib_connect( socket_info, &path_rec );\r
+       if( *lpErrno != WSAEWOULDBLOCK )\r
        {\r
-               cl_spinlock_acquire( &socket_info->mutex );\r
-\r
-               if( socket_info->socket_state == IBSP_CONNECT )\r
-               {\r
-                       /* We must be sure none destroyed our socket */\r
-                       IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_BIND );\r
-                       memset( &socket_info->peer_addr, 0, sizeof(struct sockaddr_in) );\r
-               }\r
+               /* We must be sure none destroyed our socket */\r
+               IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_BIND );\r
+               memset( &socket_info->peer_addr, 0, sizeof(struct sockaddr_in) );\r
 \r
-               cl_spinlock_release( &socket_info->mutex );\r
-\r
-               CL_ERROR( IBSP_DBG_CONN, gdbg_lvl, ("ib_connect failed (%d)\n", ret) );\r
-\r
-               *lpErrno = WSAEHOSTUNREACH;\r
-               goto error;\r
+               IBSP_ERROR( ("ib_connect failed (%d)\n", *lpErrno) );\r
        }\r
 \r
-       /* Operation is pending */\r
-       *lpErrno = WSAEWOULDBLOCK;\r
-\r
-error:\r
-       CL_EXIT( IBSP_DBG_CONN, gdbg_lvl );\r
+done:\r
+       cl_spinlock_release( &socket_info->mutex );\r
+       IBSP_EXIT( IBSP_DBG_CONN );\r
        return SOCKET_ERROR;\r
 }\r
 \r
@@ -947,9 +933,9 @@ IBSPDuplicateSocket(
                *lpErrno = WSAENOTCONN;\r
                return SOCKET_ERROR;\r
        }\r
-       cl_spinlock_release( &socket_info->mutex );\r
 \r
        ret = prepare_duplicate_socket( socket_info, dwProcessId );\r
+       cl_spinlock_release( &socket_info->mutex );\r
        if( ret )\r
        {\r
                CL_TRACE_EXIT( IBSP_DBG_CONN, gdbg_lvl,\r
@@ -1535,12 +1521,12 @@ IBSPListen(
 \r
        case IBSP_LISTEN:\r
                /* Change the backlog */\r
-               socket_info->info.listen.backlog = backlog;\r
+               ib_listen_backlog( socket_info, backlog );\r
                *lpErrno = 0;\r
                break;\r
 \r
        default:\r
-               CL_ERROR( IBSP_DBG_CONN, gdbg_lvl,\r
+               IBSP_ERROR(\r
                        ("Invalid socket_state (%s)\n",\r
                        IBSP_SOCKET_STATE_STR( socket_info->socket_state )) );\r
                *lpErrno = WSAEINVAL;\r
index a752aae..417606f 100644 (file)
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
  * SOFTWARE.\r
  *\r
- * $Id$\r
+ * $Id: ibspdll.rc 1.3 05/05/23 16:03:31-07:00 ftillier@orbuild.infiniconsys.com $\r
  */\r
 \r
 #include <ics_ver.h>\r
 \r
 #define VER_FILETYPE                           VFT_DLL\r
 #define VER_FILESUBTYPE                                VFT2_UNKNOWN\r
-\r
-#ifdef _DEBUG_\r
-#define VER_FILEDESCRIPTION_STR                "Winsock Direct for InfiniBand (Debug)"\r
-#else\r
-#define VER_FILEDESCRIPTION_STR                "Winsock Direct for InfiniBand"\r
-#endif\r
-\r
-#define VER_INTERNALNAME_STR           "ibwsd.dll"\r
-#define VER_ORIGINALFILENAME_STR       "ibwsd.dll"\r
+#define VER_FILEDESCRIPTION_STR     "SilverStorm Winsock Direct for InfiniBand"\r
+#define VER_INTERNALNAME_STR        "ibwsd.dll"\r
+#define VER_ORIGINALFILENAME_STR    "ibwsd.dll"\r
 \r
 #include <common.ver>\r
index a9b1122..67b7999 100644 (file)
@@ -195,20 +195,23 @@ ib_reject(
 int\r
 ib_accept(\r
        IN                              struct ibsp_socket_info         *socket_info,\r
-       IN                              ib_cm_req_rec_t                         *cm_req_received,\r
-               OUT                     LPINT                                           lpErrno );\r
+       IN                              ib_cm_req_rec_t                         *cm_req_received );\r
 \r
 int\r
 ib_connect(\r
        IN                              struct ibsp_socket_info         *socket_info,\r
-       IN                              ib_path_rec_t                           *path_rec,\r
-               OUT                     LPINT                                           lpErrno );\r
+       IN                              ib_path_rec_t                           *path_rec );\r
 \r
 void\r
 ib_disconnect(\r
        IN                              struct ibsp_socket_info         *socket_info,\r
        IN                              struct disconnect_reason        *reason );\r
 \r
+void\r
+ib_listen_backlog(\r
+       IN                              struct ibsp_socket_info         *socket_info,\r
+       IN                              int                                                     backlog );\r
+\r
 /* ibsp_pnp.h */\r
 ib_api_status_t\r
 register_pnp( void );\r
@@ -258,6 +261,14 @@ void
 ib_deregister_all_mr(\r
        IN                              struct mr_list                          *mem_list );\r
 \r
+int\r
+ibsp_conn_insert(\r
+       IN                              struct ibsp_socket_info         *socket_info );\r
+\r
+void\r
+ibsp_conn_remove(\r
+       IN                              struct ibsp_socket_info         *socket_info );\r
+\r
 void\r
 ibsp_post_select_event(\r
                                        struct ibsp_socket_info         *socket_info,\r
index e5d79ac..0172a84 100644 (file)
@@ -31,6 +31,7 @@
 \r
 #include <complib/cl_qlist.h>\r
 #include <complib/cl_fleximap.h>\r
+#include <complib/cl_rbmap.h>\r
 #include <complib/cl_spinlock.h>\r
 #include <complib/cl_debug.h>\r
 \r
@@ -210,6 +211,7 @@ struct cq_thread_info
 struct ibsp_socket_info\r
 {\r
        cl_list_item_t item;            /* Link to next SOCKET_INFO in the global list */\r
+       cl_rbmap_item_t conn_item;\r
        cl_spinlock_t mutex;            /* protect this structure */\r
 \r
        /* Switch socket handle created by WPUCreateSocketHandle. */\r
@@ -430,6 +432,7 @@ struct ibspdll_globals
        WSPUPCALLTABLEEX up_call_table; /* MUST keep afetr entry_count */\r
        HANDLE heap;\r
        cl_qlist_t socket_info_list;    /* List of all the created sockets */\r
+       cl_rbmap_t conn_map;    /* rb tree of all connections to ensure unique 4-tuple */\r
        cl_spinlock_t socket_info_mutex;\r
 \r
        cl_qlist_t closed_socket_info_list;     /* List of sockets in IBSP_CLOSED state */\r
index 03f7c11..2ea7ac1 100644 (file)
@@ -104,6 +104,7 @@ init_globals( void )
        cl_spinlock_init( &g_ibsp.ip_mutex );\r
 \r
        cl_qlist_init( &g_ibsp.socket_info_list );\r
+       cl_rbmap_init( &g_ibsp.conn_map );\r
        cl_spinlock_init( &g_ibsp.socket_info_mutex );\r
 \r
        cl_qlist_init( &g_ibsp.closed_socket_info_list );\r
index d008072..2926235 100644 (file)
@@ -91,6 +91,8 @@ free_socket_info(
 {\r
        IBSP_ENTER( IBSP_DBG_SI );\r
 \r
+       CL_ASSERT( !socket_info->conn_item.p_map );\r
+\r
        cl_spinlock_destroy( &socket_info->buf_mem_list.mutex );\r
        cl_spinlock_destroy( &socket_info->mutex );\r
 \r