create_name(\r
OUT char *fname,\r
IN const DWORD dwProcessId,\r
- IN const DWORD identifier )\r
+ IN const GUID *p_guid )\r
{\r
- sprintf( fname, "SilverStorm-WSD-%08lx-%08lx", dwProcessId, identifier );\r
+ sprintf( fname, "Global\\OpenIB-WSD-%08lx-"\r
+ "%08lx-%04hx-%04hx-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",\r
+ dwProcessId, p_guid->Data1, p_guid->Data2, p_guid->Data3,\r
+ (int)p_guid->Data4[0], (int)p_guid->Data4[1],\r
+ (int)p_guid->Data4[2], (int)p_guid->Data4[3],\r
+ (int)p_guid->Data4[4], (int)p_guid->Data4[5],\r
+ (int)p_guid->Data4[6], (int)p_guid->Data4[7] );\r
}\r
\r
\r
int\r
setup_duplicate_socket(\r
IN struct ibsp_socket_info *socket_info,\r
- IN DWORD identifier )\r
+ IN HANDLE h_dup_info )\r
{\r
- char fname[100];\r
- HANDLE h = NULL;\r
int ret, err;\r
struct ibsp_duplicate_info *dup_info;\r
ib_net64_t dest_port_guid;\r
ib_path_rec_t path_rec;\r
\r
- IBSP_ENTER( IBSP_DBG_CONN );\r
+ IBSP_ENTER( IBSP_DBG_DUP );\r
\r
CL_ASSERT( socket_info->socket_state == IBSP_CREATE );\r
\r
- fzprint(("%s():%d:0x%x:0x%x: socket=0x%p dwProcessId=0x%x\n", __FUNCTION__,\r
- __LINE__, GetCurrentProcessId(), GetCurrentThreadId(), socket_info));\r
-\r
-\r
- /* Find the info created and shared by the previous controlling socket. */\r
- create_name( fname, GetCurrentProcessId(), identifier );\r
-\r
- h = CreateFileMapping( INVALID_HANDLE_VALUE, // use paging file\r
- NULL, // default security attributes\r
- PAGE_READWRITE, // read access\r
- 0, // size: high 32-bits\r
- sizeof(struct ibsp_duplicate_info), // size: low 32-bits\r
- fname ); // name of map object\r
- if( h == NULL )\r
- {\r
- IBSP_ERROR( ("CreateFileMapping failed with %d\n", GetLastError()) );\r
- ret = WSAENETDOWN;\r
- goto err1;\r
- }\r
-\r
- /* Make sure this file already existed. */\r
- if( GetLastError() != ERROR_ALREADY_EXISTS )\r
- {\r
- IBSP_ERROR( ("not mapping for socket duplicate info\n") );\r
- ret = WSAENETDOWN;\r
- goto err1;\r
- }\r
-\r
/* Get a pointer to the file-mapped shared memory. */\r
- dup_info = MapViewOfFile( h, // object to map view of\r
- FILE_MAP_WRITE, // read/write access\r
- 0, // high offset: map from\r
- 0, // low offset: beginning\r
- 0 ); // default: map entire file\r
+ dup_info = MapViewOfFile( h_dup_info, FILE_MAP_READ, 0, 0, 0 );\r
if( dup_info == NULL )\r
{\r
IBSP_ERROR( ("MapViewOfFile failed with %d\n", GetLastError()) );\r
socket_info->local_addr = dup_info->local_addr;\r
socket_info->socket_options = dup_info->socket_options;\r
socket_info->duplicate.dwProcessId = dup_info->dwProcessId;\r
- socket_info->duplicate.identifier = identifier;\r
+ socket_info->duplicate.identifier = dup_info->identifier;\r
\r
- /* Get the port info */\r
- /* Find the destination IP address */\r
socket_info->port = get_port_from_ip_address( dup_info->local_addr.sin_addr );\r
if( socket_info->port == NULL )\r
{\r
}\r
\r
err1:\r
- if( h )\r
- CloseHandle( h );\r
-\r
if( socket_info->h_event )\r
{\r
CloseHandle( socket_info->h_event );\r
socket_info->h_event = NULL;\r
}\r
\r
- IBSP_EXIT( IBSP_DBG_CONN );\r
+ CloseHandle( h_dup_info );\r
+\r
+ IBSP_EXIT( IBSP_DBG_DUP );\r
return ret;\r
}\r
\r
\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
- IN DWORD dwProcessId )\r
+/* Function: IBSPDuplicateSocket\r
+\r
+ Description:\r
+ This function provides a WSAPROTOCOL_INFOW structure which can be passed\r
+ to another process to open a handle to the same socket. First we need\r
+ to translate the user socket into the provider socket and call the underlying\r
+ WSPDuplicateSocket. Note that the lpProtocolInfo structure passed into us\r
+ is an out parameter only!\r
+*/\r
+int WSPAPI\r
+IBSPDuplicateSocket(\r
+ SOCKET s,\r
+ DWORD dwProcessId,\r
+ LPWSAPROTOCOL_INFOW lpProtocolInfo,\r
+ LPINT lpErrno )\r
{\r
+ struct ibsp_socket_info *socket_info = (struct ibsp_socket_info *)s;\r
struct ibsp_duplicate_info *dup_info = NULL;\r
- int i;\r
- DWORD identifier = 0;\r
+ char fname[100];\r
+ GUID guid;\r
+ HANDLE h_dup_info, h_target_process, h_target_dup_info;\r
struct disconnect_reason reason;\r
\r
- IBSP_ENTER( IBSP_DBG_CONN );\r
+ IBSP_ENTER( IBSP_DBG_DUP );\r
\r
- fzprint(("%s():%d:0x%x:0x%x: socket=0x%p dwProcessId=0x%x \n", __FUNCTION__,\r
- __LINE__, GetCurrentProcessId(),\r
- GetCurrentThreadId(), socket_info, dwProcessId));\r
+ IBSP_TRACE4( IBSP_DBG_DUP,\r
+ ("Duplicating socket=0x%p to dwProcessId=0x%x \n",\r
+ socket_info, dwProcessId) );\r
+\r
+ cl_spinlock_acquire( &socket_info->mutex );\r
+ if( socket_info->socket_state != IBSP_CONNECTED )\r
+ {\r
+ cl_spinlock_release( &socket_info->mutex );\r
+ IBSP_TRACE_EXIT( IBSP_DBG_DUP,\r
+ ("Socket state not IBSP_CONNECTED, state=%s.\n",\r
+ IBSP_SOCKET_STATE_STR( socket_info->socket_state )) );\r
+ *lpErrno = WSAENOTCONN;\r
+ return SOCKET_ERROR;\r
+ }\r
\r
- /* First, flush all the receive buffers. There should be no send/rdma buffers left. */\r
- 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
+ cl_spinlock_release( &socket_info->mutex );\r
+\r
+ /* Create a GUID to use as unique identifier for this duplication. */\r
+ UuidCreate( &guid );\r
+ create_name( fname, dwProcessId, &guid );\r
+\r
+ h_dup_info = CreateFileMapping( INVALID_HANDLE_VALUE, NULL,\r
+ PAGE_READWRITE, 0, sizeof(struct ibsp_duplicate_info), fname );\r
+ if( !h_dup_info )\r
{\r
- CloseHandle( socket_info->duplicate.mmap_handle );\r
- socket_info->duplicate.mmap_handle = NULL;\r
+ IBSP_ERROR_EXIT(\r
+ ("CreateFileMapping for %s failed with %d\n",\r
+ fname, GetLastError()) );\r
+ *lpErrno = WSAENETDOWN;\r
+ return SOCKET_ERROR;\r
+ }\r
+\r
+ /* Get a pointer to the file-mapped shared memory. */\r
+ dup_info = MapViewOfFile( h_dup_info, FILE_MAP_WRITE, 0, 0, 0 );\r
+ if( !dup_info )\r
+ {\r
+ IBSP_ERROR_EXIT(\r
+ ("MapViewOfFile failed with %d\n", GetLastError()) );\r
+ CloseHandle( h_dup_info );\r
+ *lpErrno = WSAENETDOWN;\r
+ return SOCKET_ERROR;\r
}\r
\r
/* \r
- * Share this socket_info so the next-controlling process can get the necessary\r
- * information to create the duplicated socket. Ensure a unique identifier. \r
+ * Store addressing information so that the duplicating\r
+ * process can reconnect.\r
*/\r
- for( i = 0; i < 50; i++ )\r
+ dup_info->identifier = guid;\r
+ dup_info->socket_options = socket_info->socket_options;\r
+ dup_info->peer_addr = socket_info->peer_addr;\r
+ dup_info->local_addr = socket_info->local_addr;\r
+ dup_info->dwProcessId = dwProcessId;\r
+\r
+ /* Release the reference on the underlying file */\r
+ UnmapViewOfFile( dup_info );\r
+\r
+ /* Open the target process. */\r
+ h_target_process = OpenProcess( PROCESS_DUP_HANDLE, FALSE, dwProcessId );\r
+ if( !h_target_process )\r
{\r
- char fname[100];\r
- GUID guid;\r
-\r
- /* Create a GUID and collapse it into 32 bits. */\r
- UuidCreate( &guid );\r
- identifier = guid.Data1 ^ (guid.Data2 << 16 | guid.Data3) ^\r
- (guid.Data4[7] << 24 | guid.Data4[6] << 16 | guid.Data4[5] << 8 | guid.\r
- Data4[4]) ^ (guid.Data4[3] << 24 | guid.Data4[2] << 16 | guid.\r
- Data4[1] << 8 | guid.Data4[0]);\r
-\r
- create_name( fname, dwProcessId, identifier );\r
-\r
- socket_info->duplicate.mmap_handle = CreateFileMapping( INVALID_HANDLE_VALUE, // use paging file\r
- NULL, // default security attributes\r
- PAGE_READWRITE, // read access\r
- 0, // size: high 32-bits\r
- sizeof(struct ibsp_duplicate_info), // size: low 32-bits\r
- fname ); // name of map object\r
-\r
- if( socket_info->duplicate.mmap_handle == NULL )\r
- {\r
- IBSP_ERROR_EXIT(\r
- ("CreateFileMapping failed with %d\n", GetLastError()) );\r
- return WSAENETDOWN;\r
- }\r
-\r
- /* Make sure this identifier is unique for that process. */\r
- if( GetLastError() == ERROR_ALREADY_EXISTS )\r
- {\r
- CloseHandle( socket_info->duplicate.mmap_handle );\r
- socket_info->duplicate.mmap_handle = NULL;\r
-\r
- /* Try again. */\r
- continue;\r
- }\r
-\r
- /* Get a pointer to the file-mapped shared memory. */\r
- dup_info = MapViewOfFile( socket_info->duplicate.mmap_handle, // object to map view of\r
- FILE_MAP_WRITE, // read/write access\r
- 0, // high offset: map from\r
- 0, // low offset: beginning\r
- 0 ); // default: map entire file\r
- if( dup_info == NULL )\r
- {\r
- IBSP_ERROR_EXIT(\r
- ("MapViewOfFile failed with %d\n", GetLastError()) );\r
- CloseHandle( socket_info->duplicate.mmap_handle );\r
- socket_info->duplicate.mmap_handle = NULL;\r
- return WSAENETDOWN;\r
- }\r
+ IBSP_ERROR_EXIT(\r
+ ("OpenProcess failed with %d\n", GetLastError()) );\r
+ CloseHandle( h_dup_info );\r
+ *lpErrno = WSAENETDOWN;\r
+ return SOCKET_ERROR;\r
}\r
\r
- if( dup_info == NULL )\r
+ if( !DuplicateHandle( GetCurrentProcess(), h_dup_info,\r
+ h_target_process, &h_target_dup_info, 0, TRUE,\r
+ DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS ) )\r
{\r
- IBSP_ERROR_EXIT( ("failed to get a unique identifier\n") );\r
- CloseHandle( socket_info->duplicate.mmap_handle );\r
- socket_info->duplicate.mmap_handle = NULL;\r
- return WSAENETDOWN;\r
+ IBSP_ERROR_EXIT(\r
+ ("DuplicateHandle failed with %d\n", GetLastError()) );\r
+ CloseHandle( h_target_process );\r
+ *lpErrno = WSAENETDOWN;\r
+ return SOCKET_ERROR;\r
}\r
\r
- socket_info->duplicate.identifier = identifier;\r
+ CloseHandle( h_target_process );\r
+\r
+ CL_ASSERT( !((ULONG_PTR)h_target_dup_info >> 32) );\r
+ lpProtocolInfo->dwProviderReserved = (DWORD)(ULONG_PTR)h_target_dup_info;\r
+\r
+ socket_info->duplicate.identifier = guid;\r
\r
memset( &reason, 0, sizeof(reason) );\r
reason.type = DISC_DUPLICATING;\r
- reason.duplicating.identifier = identifier;\r
+ reason.duplicating.identifier = guid;\r
reason.duplicating.dwProcessId = dwProcessId;\r
\r
- cl_spinlock_release( &socket_info->mutex );\r
+ /*\r
+ * Flush all the receive buffers. There should be no\r
+ * send/rdma buffers left.\r
+ */\r
ib_disconnect( socket_info, &reason );\r
\r
wait_cq_drain( socket_info );\r
\r
cl_spinlock_acquire( &socket_info->mutex );\r
ib_destroy_socket( socket_info );\r
-\r
- /* Put enough info in dup_info so that the remote socket can recreate the connection. */\r
- dup_info->port_guid = socket_info->port->guid;\r
- dup_info->socket_options = socket_info->socket_options;\r
- dup_info->peer_addr = socket_info->peer_addr;\r
- dup_info->local_addr = socket_info->local_addr;\r
- dup_info->dwProcessId = dwProcessId;\r
+ cl_spinlock_release( &socket_info->mutex );\r
\r
/* And that's it */\r
- IBSP_EXIT( IBSP_DBG_CONN );\r
+ IBSP_EXIT( IBSP_DBG_DUP );\r
+ *lpErrno = 0;\r
return 0;\r
}\r
}\r
\r
\r
-/* Function: IBSPDuplicateSocket\r
-\r
- Description:\r
- This function provides a WSAPROTOCOL_INFOW structure which can be passed\r
- to another process to open a handle to the same socket. First we need\r
- to translate the user socket into the provider socket and call the underlying\r
- WSPDuplicateSocket. Note that the lpProtocolInfo structure passed into us\r
- is an out parameter only!\r
-*/\r
-static int WSPAPI\r
-IBSPDuplicateSocket(\r
- SOCKET s,\r
- DWORD dwProcessId,\r
- LPWSAPROTOCOL_INFOW lpProtocolInfo,\r
- LPINT lpErrno )\r
-{\r
- struct ibsp_socket_info *socket_info = (struct ibsp_socket_info *)s;\r
- int ret;\r
-\r
- IBSP_ENTER( IBSP_DBG_CONN );\r
-\r
- fzprint(("%s():%d:0x%x:0x%x: socket=0x%p state=%s\n", __FUNCTION__,\r
- __LINE__, GetCurrentProcessId(),\r
- GetCurrentThreadId(), s, IBSP_SOCKET_STATE_STR( socket_info->socket_state )));\r
-\r
- cl_spinlock_acquire( &socket_info->mutex );\r
- if( socket_info->socket_state != IBSP_CONNECTED )\r
- {\r
- cl_spinlock_release( &socket_info->mutex );\r
- IBSP_TRACE_EXIT( IBSP_DBG_CONN,\r
- ("Socket state not IBSP_CONNECTED, state=%s.\n",\r
- IBSP_SOCKET_STATE_STR( socket_info->socket_state )) );\r
- *lpErrno = WSAENOTCONN;\r
- return SOCKET_ERROR;\r
- }\r
-\r
- ret = prepare_duplicate_socket( socket_info, dwProcessId );\r
- cl_spinlock_release( &socket_info->mutex );\r
- if( ret )\r
- {\r
- IBSP_TRACE_EXIT( IBSP_DBG_CONN,\r
- ("prepare_duplicate_socket failed with %d\n", ret) );\r
- *lpErrno = ret;\r
- return SOCKET_ERROR;\r
- }\r
- else\r
- {\r
- IBSP_EXIT( IBSP_DBG_CONN );\r
- lpProtocolInfo->dwProviderReserved = socket_info->duplicate.identifier;\r
- *lpErrno = 0;\r
- return 0;\r
- }\r
-}\r
-\r
-\r
/* Function: IBSPEnumNetworkEvents\r
* \r
* Description:\r
IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_LISTEN );\r
\r
socket_info->listen.listen_req_param.dwProcessId = 0;\r
- socket_info->listen.listen_req_param.identifier = 0;\r
+ cl_memclr( &socket_info->listen.listen_req_param.identifier,\r
+ sizeof(socket_info->listen.listen_req_param.identifier) );\r
\r
ret = ib_listen( socket_info );\r
if( ret )\r
if( lpProtocolInfo->dwProviderReserved != 0 )\r
{\r
/* This is a duplicate socket. */\r
- *lpErrno = setup_duplicate_socket(\r
- socket_info, lpProtocolInfo->dwProviderReserved );\r
+ *lpErrno = setup_duplicate_socket( socket_info,\r
+ (HANDLE)(ULONG_PTR)lpProtocolInfo->dwProviderReserved );\r
if( *lpErrno )\r
{\r
deref_socket_info( socket_info );\r