From 756723d2d5b3ef9f72a2ebeb64745bec7dd54910 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Thu, 13 Jan 2005 06:46:22 +0000 Subject: [PATCH] Initial accept commit. Accept sockets now work although there are still problems related to shutting down the listener itself at process close time. I've tried a simple server with it and it looks good. svn path=/trunk/; revision=13021 --- reactos/drivers/lib/ip/network/ports.c | 2 + reactos/drivers/lib/ip/transport/tcp/accept.c | 34 ++++---- reactos/drivers/lib/ip/transport/tcp/tcp.c | 34 +++++++- .../drivers/lib/oskittcp/oskittcp/interface.c | 16 ++-- reactos/drivers/net/afd/afd/info.c | 56 ++++++++++-- reactos/drivers/net/afd/afd/listen.c | 45 ++++++++-- reactos/drivers/net/afd/afd/main.c | 5 +- reactos/drivers/net/afd/afd/read.c | 12 +++ reactos/drivers/net/afd/afd/tdiconn.c | 10 ++- reactos/drivers/net/afd/include/afd.h | 4 +- reactos/drivers/net/tcpip/include/tcp.h | 4 + reactos/drivers/net/tcpip/tcpip/dispatch.c | 46 +++++++++- reactos/drivers/net/tcpip/tcpip/fileobjs.c | 8 +- reactos/drivers/net/tcpip/tcpip/main.c | 4 +- reactos/include/afd/shared.h | 3 + reactos/lib/msafd/misc/dllmain.c | 86 +++++++++++++++++-- reactos/lib/msafd/misc/sndrcv.c | 2 +- reactos/lib/ws2_32/misc/catalog.c | 10 ++- reactos/lib/ws2_32/misc/dllmain.c | 9 ++ 19 files changed, 323 insertions(+), 67 deletions(-) diff --git a/reactos/drivers/lib/ip/network/ports.c b/reactos/drivers/lib/ip/network/ports.c index 6f0ab37468d..62be2ef11a3 100644 --- a/reactos/drivers/lib/ip/network/ports.c +++ b/reactos/drivers/lib/ip/network/ports.c @@ -20,6 +20,8 @@ VOID PortsStartup( PPORT_SET PortSet, RtlInitializeBitMap( &PortSet->ProtoBitmap, PortSet->ProtoBitBuffer, PortSet->PortsToOversee ); + RtlClearBits( &PortSet->ProtoBitmap, + PortSet->StartingPort, PortsToManage ); ExInitializeFastMutex( &PortSet->Mutex ); } diff --git a/reactos/drivers/lib/ip/transport/tcp/accept.c b/reactos/drivers/lib/ip/transport/tcp/accept.c index 1b79bed5aa3..40287184187 100644 --- a/reactos/drivers/lib/ip/transport/tcp/accept.c +++ b/reactos/drivers/lib/ip/transport/tcp/accept.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS TCP/IP protocol driver - * FILE: transport/tcp/tcp.c + * FILE: transport/tcp/accept.c * PURPOSE: Transmission Control Protocol Listen/Accept code * PROGRAMMERS: Art Yerkes (arty@users.sf.net) * REVISIONS: @@ -16,8 +16,7 @@ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener, NTSTATUS Status; SOCKADDR_IN OutAddr; OSK_UINT OutAddrLen; - PTA_ADDRESS RequestAddressReturn; - SOCKADDR_IN AddressConnecting; + PTA_IP_ADDRESS RequestAddressReturn; PTDI_CONNECTION_INFORMATION WhoIsConnecting; /* Unpack TDI info -- We need the return connection information @@ -38,22 +37,23 @@ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener, TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status)); if( NT_SUCCESS(Status) && Status != STATUS_PENDING ) { + RequestAddressReturn = WhoIsConnecting->RemoteAddress; + TI_DbgPrint(DEBUG_TCP,("Copying address to %x (Who %x)\n", RequestAddressReturn, WhoIsConnecting)); - RequestAddressReturn = (PTA_ADDRESS)WhoIsConnecting->RemoteAddress; - RequestAddressReturn->AddressLength = OutAddrLen; - RequestAddressReturn->AddressType = - AddressConnecting.sin_family; - TI_DbgPrint(DEBUG_TCP,("Copying address proper: from %x to %x,%x\n", - ((PCHAR)&AddressConnecting) + - sizeof(AddressConnecting.sin_family), - RequestAddressReturn->Address, - RequestAddressReturn->AddressLength)); - RtlCopyMemory( RequestAddressReturn->Address, - ((PCHAR)&AddressConnecting) + - sizeof(AddressConnecting.sin_family), - RequestAddressReturn->AddressLength ); + RequestAddressReturn->TAAddressCount = 1; + RequestAddressReturn->Address[0].AddressLength = OutAddrLen; + + /* BSD uses the first byte of the sockaddr struct as a length. + * Since windows doesn't do that we strip it */ + RequestAddressReturn->Address[0].AddressType = + (OutAddr.sin_family >> 8) & 0xff; + + RtlCopyMemory( &RequestAddressReturn->Address[0].Address, + ((PCHAR)&OutAddr) + sizeof(USHORT), + sizeof(RequestAddressReturn->Address[0].Address[0]) ); + TI_DbgPrint(DEBUG_TCP,("Done copying\n")); } @@ -151,7 +151,7 @@ NTSTATUS TCPAccept } TcpipRecursiveMutexLeave( &TCPLock ); - + TI_DbgPrint(DEBUG_TCP,("TCPAccept finished %x\n", Status)); return Status; } diff --git a/reactos/drivers/lib/ip/transport/tcp/tcp.c b/reactos/drivers/lib/ip/transport/tcp/tcp.c index c46b8ce7fa5..ea0b90c2918 100644 --- a/reactos/drivers/lib/ip/transport/tcp/tcp.c +++ b/reactos/drivers/lib/ip/transport/tcp/tcp.c @@ -30,9 +30,13 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection, PIRP Irp; PMDL Mdl; + TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n", + Connection, Connection->SocketContext)); + /* Things that can happen when we try the initial connection */ if( ((NewState & SEL_CONNECT) || (NewState & SEL_FIN)) && !(Connection->State & (SEL_CONNECT | SEL_FIN)) ) { + while( !IsListEmpty( &Connection->ConnectRequest ) ) { Connection->State |= NewState & (SEL_CONNECT | SEL_FIN); Entry = RemoveHeadList( &Connection->ConnectRequest ); @@ -529,7 +533,8 @@ NTSTATUS TCPReceiveData NTSTATUS Status; PTDI_BUCKET Bucket; - TI_DbgPrint(DEBUG_TCP,("Called for %d bytes\n", ReceiveLength)); + TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n", + ReceiveLength, Connection->SocketContext)); ASSERT_KM_POINTER(Connection->SocketContext); @@ -616,7 +621,11 @@ VOID TCPTimeout(VOID) { UINT TCPAllocatePort( UINT HintPort ) { if( HintPort ) { if( AllocatePort( &TCPPorts, HintPort ) ) return HintPort; - else return (UINT)-1; + else { + TI_DbgPrint + (MID_TRACE,("We got a hint port but couldn't allocate it\n")); + return (UINT)-1; + } } else return AllocatePortFromRange( &TCPPorts, 1024, 5000 ); } @@ -624,4 +633,25 @@ VOID TCPFreePort( UINT Port ) { DeallocatePort( &TCPPorts, Port ); } +NTSTATUS TCPGetPeerAddress +( PCONNECTION_ENDPOINT Connection, + PTRANSPORT_ADDRESS Address ) { + OSK_UINT LocalAddress, RemoteAddress; + OSK_UI16 LocalPort, RemotePort; + PTA_IP_ADDRESS AddressIP = (PTA_IP_ADDRESS)Address; + + OskitTCPGetAddress + ( Connection->SocketContext, + &LocalAddress, &LocalPort, + &RemoteAddress, &RemotePort ); + + AddressIP->TAAddressCount = 1; + AddressIP->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP; + AddressIP->Address[0].AddressType = TDI_ADDRESS_TYPE_IP; + AddressIP->Address[0].Address[0].sin_port = RemotePort; + AddressIP->Address[0].Address[0].in_addr = RemoteAddress; + + return STATUS_SUCCESS; +} + /* EOF */ diff --git a/reactos/drivers/lib/oskittcp/oskittcp/interface.c b/reactos/drivers/lib/oskittcp/oskittcp/interface.c index bb60fd5255a..5d9bb3bf70c 100644 --- a/reactos/drivers/lib/oskittcp/oskittcp/interface.c +++ b/reactos/drivers/lib/oskittcp/oskittcp/interface.c @@ -22,8 +22,8 @@ struct linker_set domain_set; OSKITTCP_EVENT_HANDLERS OtcpEvent = { 0 }; -OSK_UINT OskitDebugTraceLevel = OSK_DEBUG_ULTRA; -//OSK_UINT OskitDebugTraceLevel = 0; +//OSK_UINT OskitDebugTraceLevel = OSK_DEBUG_ULTRA; +OSK_UINT OskitDebugTraceLevel = 0; /* SPL */ unsigned cpl; @@ -295,6 +295,7 @@ int OskitTCPAccept( void *socket, struct socket *so = socket; struct sockaddr_in sa; struct mbuf mnam; + struct inpcb *inp; int namelen = 0, error = 0, s; OS_DbgPrint(OSK_MID_TRACE,("OSKITTCP: Doing accept (Finish %d)\n", @@ -308,8 +309,6 @@ int OskitTCPAccept( void *socket, s = splnet(); - OskitDumpBuffer( so, sizeof(*so) ); - #if 0 if ((head->so_options & SO_ACCEPTCONN) == 0) { splx(s); @@ -363,6 +362,13 @@ int OskitTCPAccept( void *socket, */ so = head->so_q; + inp = so ? so->so_pcb : 0; + if( inp ) { + ((struct sockaddr_in *)AddrOut)->sin_addr.s_addr = + inp->inp_faddr.s_addr; + ((struct sockaddr_in *)AddrOut)->sin_port = inp->inp_fport; + } + OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); if( FinishAccepting ) { head->so_q = so->so_q; @@ -380,8 +386,6 @@ int OskitTCPAccept( void *socket, so->so_state = SS_NBIO | SS_ISCONNECTED; - OskitDumpBuffer( so, sizeof(*so) ); - OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); if (name) { /* check sa_len before it is destroyed */ diff --git a/reactos/drivers/net/afd/afd/info.c b/reactos/drivers/net/afd/afd/info.c index 560a970e3fc..f521fade070 100644 --- a/reactos/drivers/net/afd/afd/info.c +++ b/reactos/drivers/net/afd/afd/info.c @@ -62,12 +62,14 @@ AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp, } NTSTATUS STDCALL -AfdGetSockName( PDEVICE_OBJECT DeviceObject, PIRP Irp, - PIO_STACK_LOCATION IrpSp ) { +AfdGetSockOrPeerName( PDEVICE_OBJECT DeviceObject, PIRP Irp, + PIO_STACK_LOCATION IrpSp, BOOLEAN Local ) { NTSTATUS Status = STATUS_SUCCESS; PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; - PMDL Mdl; + PMDL Mdl = NULL, SysMdl = NULL; + PTDI_CONNECTION_INFORMATION ConnInfo = NULL; + PTRANSPORT_ADDRESS TransAddr = NULL; AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB)); @@ -94,12 +96,50 @@ AfdGetSockName( PDEVICE_OBJECT DeviceObject, PIRP Irp, } _SEH_END; if( NT_SUCCESS(Status) ) { - Status = TdiQueryInformation - ( FCB->AddressFile.Object, - TDI_QUERY_ADDRESS_INFO, - Mdl ); - } + if( Local ) { + Status = TdiQueryInformation + ( FCB->AddressFile.Object, + TDI_QUERY_ADDRESS_INFO, + Mdl ); + } else { + if( !NT_SUCCESS + ( Status = TdiBuildNullConnectionInfo + ( &ConnInfo, + FCB->LocalAddress->Address[0].AddressType ) ) ) { + SysMdl = IoAllocateMdl + ( ConnInfo, + sizeof( TDI_CONNECTION_INFORMATION ) + + TaLengthOfTransportAddress + ( ConnInfo->RemoteAddress ), + FALSE, + FALSE, + NULL ); + } + if( SysMdl ) { + MmBuildMdlForNonPagedPool( SysMdl ); + Status = TdiQueryInformation + ( FCB->AddressFile.Object, + TDI_QUERY_CONNECTION_INFO, + SysMdl ); + } else Status = STATUS_NO_MEMORY; + + if( NT_SUCCESS(Status) ) { + TransAddr = + (PTRANSPORT_ADDRESS)MmMapLockedPages + ( Mdl, IoModifyAccess ); + } + + if( TransAddr ) + RtlCopyMemory( TransAddr, ConnInfo->RemoteAddress, + TaLengthOfTransportAddress + ( ConnInfo->RemoteAddress ) ); + + if( ConnInfo ) ExFreePool( ConnInfo ); + if( SysMdl ) IoFreeMdl( SysMdl ); + } + } + /* MmUnlockPages( Mdl ); */ IoFreeMdl( Mdl ); } else { diff --git a/reactos/drivers/net/afd/afd/listen.c b/reactos/drivers/net/afd/afd/listen.c index b38d4514d26..116e9336931 100644 --- a/reactos/drivers/net/afd/afd/listen.c +++ b/reactos/drivers/net/afd/afd/listen.c @@ -23,10 +23,8 @@ VOID SatisfyAccept( PIRP Irp, PFILE_OBJECT NewFileObject, FCB->State = SOCKET_STATE_CONNECTED; FCB->Connection = Qelt->Object; -#if 0 FCB->RemoteAddress = TaCopyTransportAddress( Qelt->ConnInfo->RemoteAddress ); -#endif Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_SUCCESS; @@ -40,15 +38,32 @@ VOID SatisfyAccept( PIRP Irp, PFILE_OBJECT NewFileObject, VOID SatisfyPreAccept( PIRP Irp, PAFD_TDI_OBJECT_QELT Qelt ) { PAFD_RECEIVED_ACCEPT_DATA ListenReceive = (PAFD_RECEIVED_ACCEPT_DATA)Irp->AssociatedIrp.SystemBuffer; + PTA_IP_ADDRESS IPAddr; ListenReceive->SequenceNumber = Qelt->Seq; + AFD_DbgPrint(MID_TRACE,("Giving SEQ %d to userland\n", Qelt->Seq)); -#if 0 + AFD_DbgPrint(MID_TRACE,("Socket Address (K) %x (U) %x\n", + &ListenReceive->Address, + Qelt->ConnInfo->RemoteAddress)); + TaCopyTransportAddressInPlace( &ListenReceive->Address, Qelt->ConnInfo->RemoteAddress ); -#endif - Irp->IoStatus.Information = sizeof(*ListenReceive); + IPAddr = (PTA_IP_ADDRESS)&ListenReceive->Address; + + AFD_DbgPrint(MID_TRACE,("IPAddr->TAAddressCount %d\n", + IPAddr->TAAddressCount)); + AFD_DbgPrint(MID_TRACE,("IPAddr->Address[0].AddressType %d\n", + IPAddr->Address[0].AddressType)); + AFD_DbgPrint(MID_TRACE,("IPAddr->Address[0].AddressLength %d\n", + IPAddr->Address[0].AddressLength)); + AFD_DbgPrint(MID_TRACE,("IPAddr->Address[0].Address[0].sin_port %x\n", + IPAddr->Address[0].Address[0].sin_port)); + AFD_DbgPrint(MID_TRACE,("IPAddr->Address[0].Address[0].sin_addr %x\n", + IPAddr->Address[0].Address[0].in_addr)); + + Irp->IoStatus.Information = ((PCHAR)&IPAddr[1]) - ((PCHAR)ListenReceive); Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest( Irp, IO_NETWORK_INCREMENT ); } @@ -79,8 +94,21 @@ NTSTATUS DDKAPI ListenComplete TdiCloseDevice( FCB->Connection.Handle, FCB->Connection.Object ); } else { + UINT AddressType = + FCB->LocalAddress->Address[0].AddressType; + Qelt->Object = FCB->Connection; Qelt->Seq = FCB->ConnSeq++; + AFD_DbgPrint(MID_TRACE,("Address Type: %d (RA %x)\n", + AddressType, + FCB->ListenIrp. + ConnectionReturnInfo->RemoteAddress)); + + TdiBuildNullConnectionInfo( &Qelt->ConnInfo, AddressType ); + TaCopyTransportAddressInPlace + ( Qelt->ConnInfo->RemoteAddress, + FCB->ListenIrp.ConnectionReturnInfo->RemoteAddress ); + InsertTailList( &FCB->PendingConnections, &Qelt->ListEntry ); } @@ -119,7 +147,7 @@ NTSTATUS AfdListenSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, PAFD_FCB FCB = FileObject->FsContext; PAFD_LISTEN_DATA ListenReq; - AFD_DbgPrint(MID_TRACE,("Called\n")); + AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB)); if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, TRUE ); @@ -240,7 +268,7 @@ NTSTATUS AfdAccept( PDEVICE_OBJECT DeviceObject, PIRP Irp, PendingConnObj->Seq)); if( PendingConnObj->Seq == AcceptData->SequenceNumber ) { - PFILE_OBJECT NewFileObject; + PFILE_OBJECT NewFileObject = NULL; RemoveEntryList( PendingConn ); @@ -252,6 +280,9 @@ NTSTATUS AfdAccept( PDEVICE_OBJECT DeviceObject, PIRP Irp, (PVOID *)&NewFileObject, NULL ); + ASSERT(NewFileObject != FileObject); + ASSERT(NewFileObject->FsContext != FCB); + /* We have a pending connection ... complete this irp right away */ SatisfyAccept( Irp, NewFileObject, PendingConnObj ); diff --git a/reactos/drivers/net/afd/afd/main.c b/reactos/drivers/net/afd/afd/main.c index e70d4a4f178..8899bd09e29 100644 --- a/reactos/drivers/net/afd/afd/main.c +++ b/reactos/drivers/net/afd/afd/main.c @@ -367,7 +367,10 @@ AfdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) return AfdDisconnect( DeviceObject, Irp, IrpSp ); case IOCTL_AFD_GET_SOCK_NAME: - return AfdGetSockName( DeviceObject, Irp, IrpSp ); + return AfdGetSockOrPeerName( DeviceObject, Irp, IrpSp, TRUE ); + + case IOCTL_AFD_GET_PEER_NAME: + return AfdGetSockOrPeerName( DeviceObject, Irp, IrpSp, FALSE ); case IOCTL_AFD_GET_TDI_HANDLES: AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_GET_TDI_HANDLES\n")); diff --git a/reactos/drivers/net/afd/afd/read.c b/reactos/drivers/net/afd/afd/read.c index cf83360977e..827d5a0fb4e 100644 --- a/reactos/drivers/net/afd/afd/read.c +++ b/reactos/drivers/net/afd/afd/read.c @@ -159,9 +159,14 @@ NTSTATUS DDKAPI ReceiveComplete FCB->Recv.BytesUsed = 0; if( FCB->State == SOCKET_STATE_CLOSED ) { + AFD_DbgPrint(MIN_TRACE,("!!! CLOSED SOCK GOT A RECEIVE COMPLETE !!!\n")); SocketStateUnlock( FCB ); DestroySocket( FCB ); return STATUS_SUCCESS; + } else if( FCB->State == SOCKET_STATE_LISTENING ) { + AFD_DbgPrint(MIN_TRACE,("!!! LISTENER GOT A RECEIVE COMPLETE !!!\n")); + SocketStateUnlock( FCB ); + return STATUS_UNSUCCESSFUL; } if( NT_SUCCESS(Irp->IoStatus.Status) && @@ -240,6 +245,12 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE ); + if( FCB->State != SOCKET_STATE_CONNECTED ) { + AFD_DbgPrint(MID_TRACE,("Called recv on wrong kind of socket (s%x)\n", + FCB->State)); + return STATUS_UNSUCCESSFUL; + } + if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS ) { AFD_DbgPrint(MID_TRACE,("Receive on connection-less sockets not implemented\n")); @@ -295,6 +306,7 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, return UnlockAndMaybeComplete( FCB, Status, Irp, TotalBytesCopied, NULL, TRUE ); } else { + AFD_DbgPrint(MID_TRACE,("Leaving read irp\n")); return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV ); } } diff --git a/reactos/drivers/net/afd/afd/tdiconn.c b/reactos/drivers/net/afd/afd/tdiconn.c index 2528a55aa58..45a3792356e 100644 --- a/reactos/drivers/net/afd/afd/tdiconn.c +++ b/reactos/drivers/net/afd/afd/tdiconn.c @@ -80,7 +80,8 @@ NTSTATUS TdiBuildNullConnectionInfoInPlace */ { ULONG TdiAddressSize; - + PTRANSPORT_ADDRESS TransportAddress; + TdiAddressSize = TdiAddressSizeFromType(Type); RtlZeroMemory(ConnInfo, @@ -88,8 +89,11 @@ NTSTATUS TdiBuildNullConnectionInfoInPlace TdiAddressSize); ConnInfo->OptionsLength = sizeof(ULONG); - ConnInfo->RemoteAddressLength = 0; - ConnInfo->RemoteAddress = NULL; + ConnInfo->RemoteAddressLength = TdiAddressSize; + ConnInfo->RemoteAddress = TransportAddress = + (PTRANSPORT_ADDRESS)&ConnInfo[1]; + TransportAddress->TAAddressCount = 1; + TransportAddress->Address[0].AddressType = Type; return STATUS_SUCCESS; } diff --git a/reactos/drivers/net/afd/include/afd.h b/reactos/drivers/net/afd/include/afd.h index 22bceceed26..5814364f061 100644 --- a/reactos/drivers/net/afd/include/afd.h +++ b/reactos/drivers/net/afd/include/afd.h @@ -191,8 +191,8 @@ AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp ); NTSTATUS STDCALL -AfdGetSockName( PDEVICE_OBJECT DeviceObject, PIRP Irp, - PIO_STACK_LOCATION IrpSp ); +AfdGetSockOrPeerName( PDEVICE_OBJECT DeviceObject, PIRP Irp, + PIO_STACK_LOCATION IrpSp, BOOLEAN Local ); /* listen.c */ NTSTATUS AfdWaitForListen( PDEVICE_OBJECT DeviceObject, PIRP Irp, diff --git a/reactos/drivers/net/tcpip/include/tcp.h b/reactos/drivers/net/tcpip/include/tcp.h index 08a0e4cdba1..8279db48685 100644 --- a/reactos/drivers/net/tcpip/include/tcp.h +++ b/reactos/drivers/net/tcpip/include/tcp.h @@ -164,6 +164,10 @@ UINT TCPAllocatePort( UINT HintPort ); VOID TCPFreePort( UINT Port ); +NTSTATUS TCPGetPeerAddress +( PCONNECTION_ENDPOINT Connection, + PTRANSPORT_ADDRESS TransportAddress ); + NTSTATUS TCPStartup( VOID); diff --git a/reactos/drivers/net/tcpip/tcpip/dispatch.c b/reactos/drivers/net/tcpip/tcpip/dispatch.c index c4450d66b17..dd028b3253d 100644 --- a/reactos/drivers/net/tcpip/tcpip/dispatch.c +++ b/reactos/drivers/net/tcpip/tcpip/dispatch.c @@ -580,7 +580,9 @@ NTSTATUS DispTdiQueryInformation( break; case TDI_CONNECTION_FILE: - AddrFile = ((PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext)->AddressFile; + AddrFile = + ((PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext)-> + AddressFile; break; default: @@ -605,13 +607,53 @@ NTSTATUS DispTdiQueryInformation( Address->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP; Address->Address[0].AddressType = TDI_ADDRESS_TYPE_IP; Address->Address[0].Address[0].sin_port = AddrFile->Port; - Address->Address[0].Address[0].in_addr = AddrFile->Address.Address.IPv4Address; + Address->Address[0].Address[0].in_addr = + AddrFile->Address.Address.IPv4Address; RtlZeroMemory( &Address->Address[0].Address[0].sin_zero, sizeof(Address->Address[0].Address[0].sin_zero)); return STATUS_SUCCESS; } + + case TDI_QUERY_CONNECTION_INFO: + { + PTDI_CONNECTION_INFORMATION AddressInfo; + PADDRESS_FILE AddrFile; + PCONNECTION_ENDPOINT Endpoint = NULL; + + AddressInfo = (PTDI_CONNECTION_INFORMATION) + MmGetSystemAddressForMdl(Irp->MdlAddress); + + switch ((ULONG)IrpSp->FileObject->FsContext2) { + case TDI_TRANSPORT_ADDRESS_FILE: + AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle; + break; + + case TDI_CONNECTION_FILE: + Endpoint = + (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext; + break; + + default: + TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n")); + return STATUS_INVALID_PARAMETER; + } + + if (!Endpoint) { + TI_DbgPrint(MID_TRACE, ("No connection object.\n")); + return STATUS_INVALID_PARAMETER; + } + + if (MmGetMdlByteCount(Irp->MdlAddress) < + (FIELD_OFFSET(TDI_CONNECTION_INFORMATION, RemoteAddress) + + sizeof(PVOID))) { + TI_DbgPrint(MID_TRACE, ("MDL buffer too small (ptr).\n")); + return STATUS_BUFFER_OVERFLOW; + } + + return TCPGetPeerAddress( Endpoint, AddressInfo->RemoteAddress ); + } } return STATUS_NOT_IMPLEMENTED; diff --git a/reactos/drivers/net/tcpip/tcpip/fileobjs.c b/reactos/drivers/net/tcpip/tcpip/fileobjs.c index f219bf3631b..55116adbed6 100644 --- a/reactos/drivers/net/tcpip/tcpip/fileobjs.c +++ b/reactos/drivers/net/tcpip/tcpip/fileobjs.c @@ -268,10 +268,10 @@ NTSTATUS FileOpenAddress( /* Protocol specific handling */ switch (Protocol) { case IPPROTO_TCP: - /* FIXME: If specified port is 0, a port is chosen dynamically */ - AddrFile->Port = TCPAllocatePort(Address->Address[0].Address[0].sin_port); - AddrFile->Send = NULL; /* TCPSendData */ - break; + AddrFile->Port = + TCPAllocatePort(Address->Address[0].Address[0].sin_port); + AddrFile->Send = NULL; /* TCPSendData */ + break; case IPPROTO_UDP: TI_DbgPrint(MID_TRACE,("Allocating udp port\n")); diff --git a/reactos/drivers/net/tcpip/tcpip/main.c b/reactos/drivers/net/tcpip/tcpip/main.c index ddbceccb7d8..eb5101dd974 100644 --- a/reactos/drivers/net/tcpip/tcpip/main.c +++ b/reactos/drivers/net/tcpip/tcpip/main.c @@ -9,10 +9,10 @@ */ #include "precomp.h" -//#define NDEBUG +#define NDEBUG #ifndef NDEBUG -DWORD DebugTraceLevel = MAX_TRACE | DEBUG_TCP; +DWORD DebugTraceLevel = DEBUG_ULTRA & ~(DEBUG_LOCK | DEBUG_PBUFFER); #else DWORD DebugTraceLevel = 0; #endif /* NDEBUG */ diff --git a/reactos/include/afd/shared.h b/reactos/include/afd/shared.h index bd560813470..ddf28233495 100644 --- a/reactos/include/afd/shared.h +++ b/reactos/include/afd/shared.h @@ -197,6 +197,7 @@ typedef struct _AFD_DISCONNECT_INFO { #define AFD_SELECT 9 #define AFD_DISCONNECT 10 #define AFD_GET_SOCK_NAME 11 +#define AFD_GET_PEER_NAME 12 #define AFD_GET_TDI_HANDLES 13 #define AFD_SET_INFO 14 #define AFD_GET_CONTEXT 16 @@ -245,6 +246,8 @@ typedef struct _AFD_DISCONNECT_INFO { _AFD_CONTROL_CODE(AFD_DISCONNECT, METHOD_NEITHER) #define IOCTL_AFD_GET_SOCK_NAME \ _AFD_CONTROL_CODE(AFD_GET_SOCK_NAME, METHOD_NEITHER) +#define IOCTL_AFD_GET_PEER_NAME \ + _AFD_CONTROL_CODE(AFD_GET_PEER_NAME, METHOD_NEITHER) #define IOCTL_AFD_GET_TDI_HANDLES \ _AFD_CONTROL_CODE(AFD_GET_TDI_HANDLES, METHOD_NEITHER) #define IOCTL_AFD_SET_INFO \ diff --git a/reactos/lib/msafd/misc/dllmain.c b/reactos/lib/msafd/misc/dllmain.c index a71a4e3fa3f..34e10df7448 100644 --- a/reactos/lib/msafd/misc/dllmain.c +++ b/reactos/lib/msafd/misc/dllmain.c @@ -248,10 +248,11 @@ WSPSocket( Upcalls.lpWPUModifyIFSHandle(1, (SOCKET)Sock, lpErrno); /* Return Socket Handle */ + AFD_DbgPrint(MID_TRACE,("Success %x\n", Sock)); return (SOCKET)Sock; error: - AFD_DbgPrint(MID_TRACE,("Ending\n")); + AFD_DbgPrint(MID_TRACE,("Ending %x\n", Status)); if( lpErrno ) *lpErrno = Status; @@ -981,10 +982,12 @@ WSPAccept( /* Re-enable Async Event */ SockReenableAsyncSelectEvent(Socket, FD_ACCEPT); - AFD_DbgPrint(MID_TRACE,("Socket %x\n", AcceptSocket)); - - /* Return Socket */ - return AcceptSocket; + AFD_DbgPrint(MID_TRACE,("Socket %x\n", AcceptSocket)); + + *lpErrno = 0; + + /* Return Socket */ + return AcceptSocket; } int @@ -1286,12 +1289,77 @@ INT WSPAPI WSPGetPeerName( IN SOCKET s, - OUT LPSOCKADDR name, - IN OUT LPINT namelen, + OUT LPSOCKADDR Name, + IN OUT LPINT NameLength, OUT LPINT lpErrno) { - - return 0; + IO_STATUS_BLOCK IOSB; + ULONG TdiAddressSize; + PTDI_ADDRESS_INFO TdiAddress; + PTRANSPORT_ADDRESS SocketAddress; + PSOCKET_INFORMATION Socket = NULL; + NTSTATUS Status; + HANDLE SockEvent; + + Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, + NULL, 1, FALSE ); + + if( !NT_SUCCESS(Status) ) return SOCKET_ERROR; + + /* Get the Socket Structure associate to this Socket*/ + Socket = GetSocketStructure(s); + + /* Allocate a buffer for the address */ + TdiAddressSize = FIELD_OFFSET(TDI_ADDRESS_INFO, + Address.Address[0].Address) + + Socket->SharedData.SizeOfLocalAddress; + TdiAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize); + + if ( TdiAddress == NULL ) { + NtClose( SockEvent ); + *lpErrno = WSAENOBUFS; + return SOCKET_ERROR; + } + + SocketAddress = &TdiAddress->Address; + + /* Send IOCTL */ + Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_GET_PEER_NAME, + NULL, + 0, + TdiAddress, + TdiAddressSize); + + /* Wait for return */ + if (Status == STATUS_PENDING) { + WaitForSingleObject(SockEvent, INFINITE); + Status = IOSB.Status; + } + + NtClose( SockEvent ); + + if (NT_SUCCESS(Status)) { + if (*NameLength >= SocketAddress->Address[0].AddressLength) { + Name->sa_family = SocketAddress->Address[0].AddressType; + RtlCopyMemory (Name->sa_data, + SocketAddress->Address[0].Address, + SocketAddress->Address[0].AddressLength); + HeapFree(GlobalHeap, 0, TdiAddress); + return 0; + } else { + HeapFree(GlobalHeap, 0, TdiAddress); + *lpErrno = WSAEFAULT; + return SOCKET_ERROR; + } + } + + return MsafdReturnWithErrno + ( IOSB.Status, lpErrno, 0, NULL ); } INT diff --git a/reactos/lib/msafd/misc/sndrcv.c b/reactos/lib/msafd/misc/sndrcv.c index 8ef096ff07a..7c28b66f212 100644 --- a/reactos/lib/msafd/misc/sndrcv.c +++ b/reactos/lib/msafd/misc/sndrcv.c @@ -103,7 +103,7 @@ WSPRecv( HANDLE SockEvent; PSOCKET_INFORMATION Socket; - AFD_DbgPrint(MID_TRACE,("Called\n")); + AFD_DbgPrint(MID_TRACE,("Called (%x)\n", Handle)); /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); diff --git a/reactos/lib/ws2_32/misc/catalog.c b/reactos/lib/ws2_32/misc/catalog.c index 849dbba86af..b8d59f9419f 100644 --- a/reactos/lib/ws2_32/misc/catalog.c +++ b/reactos/lib/ws2_32/misc/catalog.c @@ -282,11 +282,11 @@ VOID CreateCatalog(VOID) Provider->Mapping = HeapAlloc(GlobalHeap, 0, - 5 * sizeof(WINSOCK_MAPPING) + 3 * sizeof(DWORD)); + 6 * sizeof(WINSOCK_MAPPING) + 3 * sizeof(DWORD)); if (!Provider->Mapping) return; - Provider->Mapping->Rows = 5; + Provider->Mapping->Rows = 6; Provider->Mapping->Columns = 3; Provider->Mapping->Mapping[0].AddressFamily = AF_INET; @@ -307,7 +307,11 @@ VOID CreateCatalog(VOID) Provider->Mapping->Mapping[4].AddressFamily = AF_INET; Provider->Mapping->Mapping[4].SocketType = SOCK_RAW; - Provider->Mapping->Mapping[4].Protocol = 0; + Provider->Mapping->Mapping[4].Protocol = IPPROTO_ICMP; + + Provider->Mapping->Mapping[5].AddressFamily = AF_INET; + Provider->Mapping->Mapping[5].SocketType = SOCK_RAW; + Provider->Mapping->Mapping[5].Protocol = 0; #endif } diff --git a/reactos/lib/ws2_32/misc/dllmain.c b/reactos/lib/ws2_32/misc/dllmain.c index 3813a05b811..aaaf8668dc3 100644 --- a/reactos/lib/ws2_32/misc/dllmain.c +++ b/reactos/lib/ws2_32/misc/dllmain.c @@ -552,6 +552,15 @@ WSAAccept( WSASetLastError(Errno); } + if( addr ) { + LPSOCKADDR_IN sa = (LPSOCKADDR_IN)addr; + WS_DbgPrint(MAX_TRACE,("Returned address: %d %s:%d (len %d)\n", + sa->sin_family, + inet_ntoa(sa->sin_addr), + ntohs(sa->sin_port), + *addrlen)); + } + return Socket; }