[IP/OSKITTCP]

- Fix a race condition that occurs when the socket is closed by the remote host while waiting on OSKLock to perform a socket operation and results in accessing freed memory

svn path=/trunk/; revision=52718
This commit is contained in:
Cameron Gutman 2011-07-17 17:37:36 +00:00
parent 17c51414f2
commit b38aed5d19
9 changed files with 215 additions and 199 deletions

View file

@ -252,6 +252,7 @@ typedef struct _TDI_BUCKET {
(TCB) in TCP terminology. The FileObject->FsContext2 field holds a pointer
to this structure */
typedef struct _CONNECTION_ENDPOINT {
PVOID SocketContext; /* Context for lower layer (MUST be first member in struct) */
LIST_ENTRY ListEntry; /* Entry on list */
LONG RefCount; /* Reference count */
OBJECT_FREE_ROUTINE Free; /* Routine to use to free resources for the object */
@ -259,7 +260,6 @@ typedef struct _CONNECTION_ENDPOINT {
KIRQL OldIrql; /* The old irql is stored here for use in HandleSignalledConnection */
PVOID ClientContext; /* Pointer to client context information */
PADDRESS_FILE AddressFile; /* Associated address file object (NULL if none) */
PVOID SocketContext; /* Context for lower layer */
/* Requests */
LIST_ENTRY ConnectRequest; /* Queued connect rqueusts */

View file

@ -28,7 +28,7 @@ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener,
Request->ReturnConnectionInformation;
Status = TCPTranslateError
( OskitTCPAccept( Listener->SocketContext,
( OskitTCPAccept( Listener,
&Connection->SocketContext,
Connection,
&OutAddr,
@ -75,9 +75,6 @@ NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) {
TI_DbgPrint(DEBUG_TCP,("TCPListen started\n"));
TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n",
Connection->SocketContext));
if (Connection->AddressFile->Port)
{
AddressToBind.sin_family = AF_INET;
@ -88,7 +85,7 @@ NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) {
TI_DbgPrint(DEBUG_TCP,("AddressToBind - %x:%x\n", AddressToBind.sin_addr, AddressToBind.sin_port));
/* Perform an explicit bind */
Status = TCPTranslateError(OskitTCPBind(Connection->SocketContext,
Status = TCPTranslateError(OskitTCPBind(Connection,
&AddressToBind,
sizeof(AddressToBind)));
}
@ -99,7 +96,7 @@ NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) {
}
if (NT_SUCCESS(Status))
Status = TCPTranslateError( OskitTCPListen( Connection->SocketContext, Backlog ) );
Status = TCPTranslateError( OskitTCPListen( Connection, Backlog ) );
if (NT_SUCCESS(Status))
{

View file

@ -56,8 +56,8 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
if (ClientInfo.Unlocked)
LockObjectAtDpcLevel(Connection);
TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n",
Connection, Connection->SocketContext));
TI_DbgPrint(MID_TRACE,("Handling signalled state on %x\n",
Connection));
/* Things that can happen when we try the initial connection */
if( Connection->SignalState & (SEL_CONNECT | SEL_FIN | SEL_ERROR) ) {
@ -68,7 +68,7 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
if (Connection->SignalState & SEL_ERROR)
{
Bucket->Status = TCPTranslateError(OskitTCPGetSocketError(Connection->SocketContext));
Bucket->Status = TCPTranslateError(OskitTCPGetSocketError(Connection));
}
else if (Connection->SignalState & SEL_FIN)
{
@ -107,7 +107,7 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
if (Connection->SignalState & SEL_ERROR)
{
Status = TCPTranslateError(OskitTCPGetSocketError(Connection->SocketContext));
Status = TCPTranslateError(OskitTCPGetSocketError(Connection));
}
else if (Connection->SignalState & SEL_FIN)
{
@ -161,15 +161,11 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
("Reading %d bytes to %x\n", RecvLen, RecvBuffer));
TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
TI_DbgPrint
(DEBUG_TCP,
("Connection->SocketContext: %x\n",
Connection->SocketContext));
TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer));
if (Connection->SignalState & SEL_ERROR)
{
Status = TCPTranslateError(OskitTCPGetSocketError(Connection->SocketContext));
Status = TCPTranslateError(OskitTCPGetSocketError(Connection));
}
else if (Connection->SignalState & SEL_FIN)
{
@ -178,7 +174,7 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
}
else
{
Status = TCPTranslateError(OskitTCPRecv(Connection->SocketContext,
Status = TCPTranslateError(OskitTCPRecv(Connection,
RecvBuffer,
RecvLen,
&Received,
@ -227,14 +223,10 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
("Writing %d bytes to %x\n", SendLen, SendBuffer));
TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
TI_DbgPrint
(DEBUG_TCP,
("Connection->SocketContext: %x\n",
Connection->SocketContext));
if (Connection->SignalState & SEL_ERROR)
{
Status = TCPTranslateError(OskitTCPGetSocketError(Connection->SocketContext));
Status = TCPTranslateError(OskitTCPGetSocketError(Connection));
}
else if (Connection->SignalState & SEL_FIN)
{
@ -243,7 +235,7 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
}
else
{
Status = TCPTranslateError(OskitTCPSend(Connection->SocketContext,
Status = TCPTranslateError(OskitTCPSend(Connection,
SendBuffer,
SendLen,
&Sent,
@ -275,7 +267,7 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
if (Connection->SignalState & SEL_ERROR)
{
Status = TCPTranslateError(OskitTCPGetSocketError(Connection->SocketContext));
Status = TCPTranslateError(OskitTCPGetSocketError(Connection));
}
else if (Connection->SignalState & SEL_FIN)
{
@ -288,7 +280,7 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
if (IsListEmpty(&Connection->SendRequest))
{
/* Send queue is empty so we're good to go */
Status = TCPTranslateError(OskitTCPShutdown(Connection->SocketContext, FWRITE));
Status = TCPTranslateError(OskitTCPShutdown(Connection, FWRITE));
}
else
{
@ -341,7 +333,7 @@ DisconnectTimeoutDpc(PKDPC Dpc,
LockObjectAtDpcLevel(Connection);
/* We timed out waiting for pending sends so force it to shutdown */
OskitTCPShutdown(Connection->SocketContext, FWRITE);
OskitTCPShutdown(Connection, FWRITE);
while (!IsListEmpty(&Connection->SendRequest))
{
@ -439,9 +431,6 @@ NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection,
ASSERT_KM_POINTER(Connection->SocketContext);
TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n",
Connection->SocketContext));
UnlockObject(Connection, OldIrql);
return Status;
@ -781,7 +770,7 @@ NTSTATUS TCPConnect
AddressToBind.sin_port = Connection->AddressFile->Port;
/* Perform an explicit bind */
Status = TCPTranslateError(OskitTCPBind(Connection->SocketContext,
Status = TCPTranslateError(OskitTCPBind(Connection,
&AddressToBind,
sizeof(AddressToBind)));
}
@ -800,7 +789,7 @@ NTSTATUS TCPConnect
AddressToConnect.sin_port = RemotePort;
Status = TCPTranslateError
( OskitTCPConnect( Connection->SocketContext,
( OskitTCPConnect( Connection,
&AddressToConnect,
sizeof(AddressToConnect) ) );
@ -874,7 +863,7 @@ NTSTATUS TCPDisconnect
if (IsListEmpty(&Connection->SendRequest))
{
/* Send queue is empty so we're good to go */
Status = TCPTranslateError(OskitTCPShutdown(Connection->SocketContext, FWRITE));
Status = TCPTranslateError(OskitTCPShutdown(Connection, FWRITE));
UnlockObject(Connection, OldIrql);
@ -884,7 +873,7 @@ NTSTATUS TCPDisconnect
/* Check if the timeout was 0 */
if (Timeout && Timeout->QuadPart == 0)
{
OskitTCPShutdown(Connection->SocketContext, FWRITE);
OskitTCPShutdown(Connection, FWRITE);
while (!IsListEmpty(&Connection->SendRequest))
{
@ -947,7 +936,7 @@ NTSTATUS TCPDisconnect
}
/* An abort never pends; we just drop everything and complete */
Status = TCPTranslateError(OskitTCPShutdown(Connection->SocketContext, FWRITE | FREAD));
Status = TCPTranslateError(OskitTCPShutdown(Connection, FWRITE | FREAD));
UnlockObject(Connection, OldIrql);
@ -991,41 +980,21 @@ NTSTATUS TCPClose
( PCONNECTION_ENDPOINT Connection )
{
KIRQL OldIrql;
NTSTATUS Status;
PVOID Socket;
LockObject(Connection, &OldIrql);
Socket = Connection->SocketContext;
Connection->SocketContext = NULL;
/* We should not be associated to an address file at this point */
ASSERT(!Connection->AddressFile);
/* Don't try to close again if the other side closed us already */
if (Socket)
{
/* We need to close here otherwise oskit will never indicate
* SEL_FIN and we will never fully close the connection */
Status = TCPTranslateError( OskitTCPClose( Socket ) );
OskitTCPClose(Connection);
if (!NT_SUCCESS(Status))
{
Connection->SocketContext = Socket;
UnlockObject(Connection, OldIrql);
return Status;
}
}
else
{
/* We are already closed by the other end so return success */
Status = STATUS_SUCCESS;
}
Connection->SocketContext = NULL;
UnlockObject(Connection, OldIrql);
DereferenceObject(Connection);
return Status;
return STATUS_SUCCESS;
}
NTSTATUS TCPReceiveData
@ -1042,9 +1011,6 @@ NTSTATUS TCPReceiveData
PTDI_BUCKET Bucket;
KIRQL OldIrql;
TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n",
ReceiveLength, Connection->SocketContext));
NdisQueryBuffer( Buffer, &DataBuffer, &DataLen );
TI_DbgPrint(DEBUG_TCP,("TCP>|< Got an MDL %x (%x:%d)\n", Buffer, DataBuffer, DataLen));
@ -1053,7 +1019,7 @@ NTSTATUS TCPReceiveData
Status = TCPTranslateError
( OskitTCPRecv
( Connection->SocketContext,
( Connection,
DataBuffer,
DataLen,
&Received,
@ -1104,15 +1070,10 @@ NTSTATUS TCPSendData
LockObject(Connection, &OldIrql);
TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n",
SendLength, Connection->SocketContext));
TI_DbgPrint(DEBUG_TCP,("Connection = %x\n", Connection));
TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext = %x\n",
Connection->SocketContext));
Status = TCPTranslateError
( OskitTCPSend( Connection->SocketContext,
( OskitTCPSend( Connection,
(OSK_PCHAR)BufferData, SendLength,
&Sent, 0 ) );
@ -1173,7 +1134,7 @@ NTSTATUS TCPGetSockAddress
LockObject(Connection, &OldIrql);
Status = TCPTranslateError(OskitTCPGetAddress(Connection->SocketContext,
Status = TCPTranslateError(OskitTCPGetAddress(Connection,
&LocalAddress, &LocalPort,
&RemoteAddress, &RemotePort));

View file

@ -5,7 +5,8 @@ include_directories(
include/freebsd/sys/include
include/freebsd/dev/include
include/freebsd/net/include
include)
include
${REACTOS_SOURCE_DIR}/drivers/network/tcpip/include)
add_definitions(
-D__NTDRIVER__

View file

@ -11,4 +11,12 @@ void oskit_bufio_map(void *srcbuf, void**dstbuf, int off, int len);
#define osenv_sleeprec_t void*
/* We can do this safely because SocketContext will always
* be the first member in the real CONNECTION_ENDPOINT struct
*/
typedef struct _FAKE_CONNECTION_ENDPOINT
{
void *SocketContext;
} *PCONNECTION_ENDPOINT;
#endif

View file

@ -104,67 +104,67 @@ extern void InitOskitTCP( void );
extern void DeinitOskitTCP( void );
extern void TimerOskitTCP( int FastTimer, int SlowTimer );
extern void OskitDumpBuffer( OSK_PCHAR Data, OSK_UINT Len );
extern int OskitTCPShutdown( void *socket, int disconn_type );
extern int OskitTCPShutdown( PCONNECTION_ENDPOINT connection, int disconn_type );
extern int OskitTCPSocket( void *Connection, void **ConnectionContext,
int Af, int Type, int Proto );
extern void RegisterOskitTCPEventHandlers
( POSKITTCP_EVENT_HANDLERS EventHandlers );
extern void OskitTCPReceiveDatagram( OSK_PCHAR Data, OSK_UINT Len,
OSK_UINT IpHeaderLen );
extern int OskitTCPReceive( void *socket,
extern int OskitTCPReceive( PCONNECTION_ENDPOINT connection,
void *Addr,
OSK_PCHAR Data,
OSK_UINT Len,
OSK_UINT *OutLen,
OSK_UINT Flags );
extern int OskitTCPSend( void *socket,
extern int OskitTCPSend( PCONNECTION_ENDPOINT connection,
OSK_PCHAR Data,
OSK_UINT Len,
OSK_UINT *OutLen,
OSK_UINT Flags );
extern int OskitTCPConnect( void *socket,
extern int OskitTCPConnect( PCONNECTION_ENDPOINT connection,
void *nam, OSK_UINT namelen );
extern int OskitTCPClose( void *socket );
extern int OskitTCPClose( PCONNECTION_ENDPOINT connection );
extern int OskitTCPBind( void *socket,
extern int OskitTCPBind( PCONNECTION_ENDPOINT connection,
void *nam, OSK_UINT namelen );
extern int OskitTCPAccept( void *socket, void **new_socket,
extern int OskitTCPAccept( PCONNECTION_ENDPOINT connection, void **new_socket,
void *context, void *addr_out,
OSK_UINT addr_len,
OSK_UINT *out_addr_len,
OSK_UINT finish_accept );
extern int OskitTCPListen( void *socket, int backlog );
extern int OskitTCPListen( PCONNECTION_ENDPOINT connection, int backlog );
extern int OskitTCPRecv( void *connection,
extern int OskitTCPRecv( PCONNECTION_ENDPOINT connection,
OSK_PCHAR Data,
OSK_UINT Len,
OSK_UINT *OutLen,
OSK_UINT Flags );
int OskitTCPGetAddress( void *socket,
int OskitTCPGetAddress( PCONNECTION_ENDPOINT connection,
OSK_UINT *LocalAddress,
OSK_UI16 *LocalPort,
OSK_UINT *RemoteAddress,
OSK_UI16 *RemotePort );
int OskitTCPGetSockOpt(void *socket,
int OskitTCPGetSockOpt(PCONNECTION_ENDPOINT connection,
int level,
int optname,
char *buffer,
int *size);
int OskitTCPSetSockOpt(void *socket,
int OskitTCPSetSockOpt(PCONNECTION_ENDPOINT connection,
int level,
int optname,
char *buffer,
int size);
int OskitTCPDisconnect(void *socket);
int OskitTCPDisconnect(PCONNECTION_ENDPOINT connection);
int OskitTCPGetSocketError(void *socket);
int OskitTCPGetSocketError(PCONNECTION_ENDPOINT connection);
#undef errno

View file

@ -10,6 +10,7 @@
<include base="oskittcp">include/freebsd/dev/include</include>
<include base="oskittcp">include/freebsd/net/include</include>
<include base="oskittcp">include</include>
<include base="tcpip">include</include>
<directory name="oskittcp">
<file>defaults.c</file>
<file>in.c</file>

View file

@ -1,3 +1,4 @@
#include <osenv.h>
#include <oskittcp.h>
#include <oskitdebug.h>
#include <net/raw_cb.h>
@ -136,33 +137,25 @@ int OskitTCPSocket( void *context,
OSKLock();
error = socreate(domain, &so, type, proto);
if( !error ) {
*aso = so;
so->so_connection = context;
InitializeSocketFlags(so);
*aso = so;
}
OSKUnlock();
return error;
}
int OskitTCPRecv( void *connection,
int OskitTCPRecv( PCONNECTION_ENDPOINT connection,
OSK_PCHAR Data,
OSK_UINT Len,
OSK_UINT *OutLen,
OSK_UINT Flags ) {
#if DBG
struct socket *so = connection;
#endif
OSK_UINT Flags )
{
struct uio uio = { 0 };
struct iovec iov = { 0 };
int error = 0;
int tcp_flags = 0;
if (!connection)
return OSK_ESHUTDOWN;
OS_DbgPrint(OSK_MID_TRACE,
("so->so_state %x\n", so->so_state));
if( Flags & OSK_MSG_OOB ) tcp_flags |= MSG_OOB;
if( Flags & OSK_MSG_DONTWAIT ) tcp_flags |= MSG_DONTWAIT;
@ -178,11 +171,16 @@ int OskitTCPRecv( void *connection,
uio.uio_rw = UIO_READ;
uio.uio_procp = NULL;
OS_DbgPrint(OSK_MID_TRACE,("Reading %d bytes from TCP:\n", Len));
OSKLock();
error = soreceive( connection, NULL, &uio, NULL, NULL /* SCM_RIGHTS */,
&tcp_flags );
if (connection->SocketContext)
{
OS_DbgPrint(OSK_MID_TRACE,("Reading %d bytes from TCP:\n", Len));
error = soreceive(connection->SocketContext, NULL, &uio, NULL, NULL, &tcp_flags);
}
else
{
error = OSK_ESHUTDOWN;
}
OSKUnlock();
if (error == 0) *OutLen = Len - uio.uio_resid;
@ -190,17 +188,13 @@ int OskitTCPRecv( void *connection,
return error;
}
int OskitTCPBind( void *socket,
void *nam, OSK_UINT namelen ) {
int error = EFAULT;
struct socket *so = socket;
int OskitTCPBind(PCONNECTION_ENDPOINT connection, void *nam, OSK_UINT namelen)
{
int error;
struct mbuf sabuf;
struct sockaddr addr;
OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", socket));
if (!socket)
return OSK_ESHUTDOWN;
OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", connection));
if( nam )
addr = *((struct sockaddr *)nam);
@ -213,23 +207,27 @@ int OskitTCPBind( void *socket,
addr.sa_len = sizeof(struct sockaddr);
OSKLock();
error = sobind(so, &sabuf);
if (connection->SocketContext)
{
error = sobind(connection->SocketContext, &sabuf);
}
else
{
error = OSK_ESHUTDOWN;
}
OSKUnlock();
OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error));
return (error);
}
int OskitTCPConnect( void *socket, void *nam, OSK_UINT namelen ) {
struct socket *so = socket;
int error = EFAULT;
int OskitTCPConnect( PCONNECTION_ENDPOINT connection, void *nam, OSK_UINT namelen )
{
int error;
struct mbuf sabuf;
struct sockaddr addr;
OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", socket));
if (!socket)
return OSK_ESHUTDOWN;
OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", connection));
OS_DbgPrint(OSK_MIN_TRACE,("Nam: %x\n", nam));
@ -244,64 +242,79 @@ int OskitTCPConnect( void *socket, void *nam, OSK_UINT namelen ) {
addr.sa_len = sizeof(struct sockaddr);
OSKLock();
error = soconnect(so, &sabuf);
if (connection->SocketContext)
{
error = soconnect(connection->SocketContext, &sabuf);
if (!error) error = OSK_EINPROGRESS;
}
else
{
error = OSK_ESHUTDOWN;
}
OSKUnlock();
if (error == 0) error = OSK_EINPROGRESS;
OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error));
return (error);
}
int OskitTCPDisconnect(void *socket)
int OskitTCPDisconnect(PCONNECTION_ENDPOINT connection)
{
int error;
if (!socket)
return OSK_ESHUTDOWN;
OSKLock();
error = sodisconnect(socket);
if (connection->SocketContext)
{
error = sodisconnect(connection->SocketContext);
}
else
{
error = OSK_ESHUTDOWN;
}
OSKUnlock();
return error;
}
int OskitTCPShutdown( void *socket, int disconn_type ) {
int OskitTCPShutdown(PCONNECTION_ENDPOINT connection, int disconn_type) {
int error;
if (!socket)
return OSK_ESHUTDOWN;
OSKLock();
error = soshutdown( socket, disconn_type );
if (connection->SocketContext)
{
error = soshutdown(connection->SocketContext, disconn_type);
}
else
{
error = OSK_ESHUTDOWN;
}
OSKUnlock();
return error;
}
int OskitTCPClose( void *socket ) {
int OskitTCPClose( PCONNECTION_ENDPOINT connection ) {
int error;
if (!socket)
return OSK_ESHUTDOWN;
OSKLock();
error = soclose( socket );
if (connection->SocketContext)
{
error = soclose(connection->SocketContext);
}
else
{
error = OSK_ESHUTDOWN;
}
OSKUnlock();
return error;
}
int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len,
int OskitTCPSend( PCONNECTION_ENDPOINT connection, OSK_PCHAR Data, OSK_UINT Len,
OSK_UINT *OutLen, OSK_UINT flags ) {
int error;
struct uio uio;
struct iovec iov;
if (!socket)
return OSK_ESHUTDOWN;
iov.iov_len = Len;
iov.iov_base = (char *)Data;
uio.uio_iov = &iov;
@ -313,33 +326,36 @@ int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len,
uio.uio_procp = NULL;
OSKLock();
error = sosend( socket, NULL, &uio, NULL, NULL, 0 );
if (connection->SocketContext)
{
error = sosend( connection->SocketContext, NULL, &uio, NULL, NULL, 0 );
if (!error) *OutLen = Len - uio.uio_resid;
}
else
{
error = OSK_ESHUTDOWN;
}
OSKUnlock();
if (error == 0) *OutLen = Len - uio.uio_resid;
return error;
}
int OskitTCPAccept( void *socket,
int OskitTCPAccept( PCONNECTION_ENDPOINT connection,
void **new_socket,
void *context,
void *AddrOut,
OSK_UINT AddrLen,
OSK_UINT *OutAddrLen,
OSK_UINT FinishAccepting ) {
struct socket *head = (void *)socket;
struct socket *head;
struct sockaddr *name = (struct sockaddr *)AddrOut;
struct socket **newso = (struct socket **)new_socket;
struct socket *so = socket;
struct socket *so;
struct sockaddr_in sa;
struct mbuf mnam;
struct inpcb *inp;
int namelen = 0, error = 0, s;
if (!socket)
return OSK_ESHUTDOWN;
if (!new_socket)
return OSK_EINVAL;
@ -351,8 +367,14 @@ int OskitTCPAccept( void *socket,
namelen = *OutAddrLen;
OSKLock();
s = splnet();
head = connection->SocketContext;
if (!head)
{
error = OSK_ESHUTDOWN;
goto out;
}
if ((head->so_options & SO_ACCEPTCONN) == 0) {
OS_DbgPrint(OSK_MID_TRACE,("OSKITTCP: head->so_options = %x, wanted bit %x\n",
@ -452,7 +474,7 @@ void OskitTCPReceiveDatagram( OSK_PCHAR Data, OSK_UINT Len,
/* The buffer Ip is freed by tcp_input */
}
int OskitTCPSetSockOpt(void *socket,
int OskitTCPSetSockOpt(PCONNECTION_ENDPOINT connection,
int level,
int optname,
char *buffer,
@ -461,32 +483,36 @@ int OskitTCPSetSockOpt(void *socket,
struct mbuf *m;
int error;
if (!socket)
return OSK_ESHUTDOWN;
if (size >= MLEN)
return OSK_EINVAL;
OSKLock();
m = m_get(M_WAIT, MT_SOOPTS);
if (!m)
if (connection->SocketContext)
{
OSKUnlock();
return OSK_ENOMEM;
m = m_get(M_WAIT, MT_SOOPTS);
if (!m)
{
OSKUnlock();
return OSK_ENOMEM;
}
m->m_len = size;
memcpy(m->m_data, buffer, size);
/* m is freed by sosetopt */
error = sosetopt(connection->SocketContext, level, optname, m);
}
else
{
error = OSK_ESHUTDOWN;
}
m->m_len = size;
memcpy(m->m_data, buffer, size);
/* m is freed by sosetopt */
error = sosetopt(socket, level, optname, m);
OSKUnlock();
return error;
}
int OskitTCPGetSockOpt(void *socket,
int OskitTCPGetSockOpt(PCONNECTION_ENDPOINT connection,
int level,
int optname,
char *buffer,
@ -495,41 +521,49 @@ int OskitTCPGetSockOpt(void *socket,
int error, oldsize = *size;
struct mbuf *m;
if (!socket)
return OSK_ESHUTDOWN;
OSKLock();
error = sogetopt(socket, level, optname, &m);
if (!error)
if (connection->SocketContext)
{
*size = m->m_len;
if (!buffer || oldsize < m->m_len)
error = sogetopt(connection->SocketContext, level, optname, &m);
if (!error)
{
*size = m->m_len;
if (!buffer || oldsize < m->m_len)
{
m_freem(m);
OSKUnlock();
return OSK_EINVAL;
}
memcpy(buffer, m->m_data, m->m_len);
m_freem(m);
OSKUnlock();
return OSK_EINVAL;
}
memcpy(buffer, m->m_data, m->m_len);
m_freem(m);
}
else
{
error = OSK_ESHUTDOWN;
}
OSKUnlock();
return error;
}
int OskitTCPListen( void *socket, int backlog ) {
int OskitTCPListen( PCONNECTION_ENDPOINT connection, int backlog ) {
int error;
if (!socket)
return OSK_ESHUTDOWN;
OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", socket));
OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", connection));
OSKLock();
error = solisten( socket, backlog );
if (connection->SocketContext)
{
error = solisten(connection->SocketContext, backlog);
}
else
{
error = OSK_ESHUTDOWN;
}
OSKUnlock();
OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error));
@ -537,18 +571,22 @@ int OskitTCPListen( void *socket, int backlog ) {
return error;
}
int OskitTCPSetAddress( void *socket,
int OskitTCPSetAddress( PCONNECTION_ENDPOINT connection,
OSK_UINT LocalAddress,
OSK_UI16 LocalPort,
OSK_UINT RemoteAddress,
OSK_UI16 RemotePort ) {
struct socket *so = socket;
struct socket *so;
struct inpcb *inp;
if (!socket)
return OSK_ESHUTDOWN;
OSKLock();
so = connection->SocketContext;
if (!so)
{
OSKUnlock();
return OSK_ESHUTDOWN;
}
inp = (struct inpcb *)so->so_pcb;
if (!inp)
{
@ -565,18 +603,22 @@ int OskitTCPSetAddress( void *socket,
return 0;
}
int OskitTCPGetAddress( void *socket,
int OskitTCPGetAddress( PCONNECTION_ENDPOINT connection,
OSK_UINT *LocalAddress,
OSK_UI16 *LocalPort,
OSK_UINT *RemoteAddress,
OSK_UI16 *RemotePort ) {
struct socket *so = socket;
struct socket *so;
struct inpcb *inp;
if (!socket)
return OSK_ESHUTDOWN;
OSKLock();
so = connection->SocketContext;
if (!so)
{
OSKUnlock();
return OSK_ESHUTDOWN;
}
inp = (struct inpcb *)so->so_pcb;
if (!inp)
{
@ -593,15 +635,20 @@ int OskitTCPGetAddress( void *socket,
return 0;
}
int OskitTCPGetSocketError(void *socket) {
struct socket *so = socket;
int OskitTCPGetSocketError(PCONNECTION_ENDPOINT connection) {
struct socket *so;
int error;
if (!socket)
return OSK_ESHUTDOWN;
OSKLock();
error = so->so_error;
so = connection->SocketContext;
if (so)
{
error = so->so_error;
}
else
{
error = OSK_ESHUTDOWN;
}
OSKUnlock();
return error;

View file

@ -1,3 +1,4 @@
#include <osenv.h>
#include <oskittcp.h>
#include <sys/callout.h>
#include <oskitfreebsd.h>