1
0
mirror of https://github.com/solemnwarning/ipxwrapper synced 2024-12-30 16:45:37 +01:00

Bodge asynchronous connects to almost work as they should.

This commit is contained in:
Daniel Collins 2014-01-21 20:15:27 +00:00
parent a930a972df
commit 3be40b6e63
5 changed files with 74 additions and 1 deletions

View File

@ -20,3 +20,4 @@ EXPORTS
getpeername
listen
accept
WSAAsyncSelect

View File

@ -47,6 +47,7 @@
#define IPX_IS_SPX (int)(1<<10)
#define IPX_IS_SPXII (int)(1<<11)
#define IPX_LISTENING (int)(1<<12)
#define IPX_CONNECT_OK (int)(1<<13)
typedef struct ipx_socket ipx_socket;
typedef struct ipx_packet ipx_packet;
@ -152,5 +153,6 @@ int PASCAL r_send(SOCKET fd, const char *buf, int len, int flags);
int PASCAL r_getpeername(SOCKET fd, struct sockaddr *addr, int *addrlen);
int PASCAL r_listen(SOCKET s, int backlog);
SOCKET PASCAL r_accept(SOCKET s, struct sockaddr *addr, int *addrlen);
int PASCAL r_WSAAsyncSelect(SOCKET s, HWND hWnd, unsigned int wMsg, long lEvent);
#endif /* !IPXWRAPPER_H */

View File

@ -33,3 +33,5 @@ r_connect:4
r_send:4
r_getpeername:4
inet_ntoa:4
__WSAFDIsSet:4
r_WSAAsyncSelect:4

View File

@ -1724,12 +1724,57 @@ static int _connect_spx(ipx_socket *sock, struct sockaddr_ipx *ipxaddr)
if(r_connect(sock->fd, (struct sockaddr*)(&in_addr), sizeof(in_addr)) == -1)
{
if(WSAGetLastError() == WSAEWOULDBLOCK)
{
/* The socket is in non-blocking mode, so we wait for
* the asynchronous connect call to complete.
*
* Keeping it synchronous until it is proven this breaks
* something for simplicity.
*/
fd_set w_fdset;
FD_ZERO(&w_fdset);
FD_SET(sock->fd, &w_fdset);
fd_set e_fdset;
FD_ZERO(&e_fdset);
FD_SET(sock->fd, &e_fdset);
if(select(1, NULL, &w_fdset, &e_fdset, NULL) == 1 && FD_ISSET(sock->fd, &w_fdset))
{
goto CONNECTED;
}
int errnum, len = sizeof(int);
getsockopt(sock->fd, SOL_SOCKET, SO_ERROR, (char*)(&errnum), &len);
log_printf(LOG_DEBUG, "Connection failed: %s", w32_error(errnum));
unlock_sockets();
WSASetLastError(WSAEWOULDBLOCK);
return -1;
}
unlock_sockets();
return -1;
}
CONNECTED:
log_printf(LOG_DEBUG, "Connection succeeded");
/* Set the IPX_CONNECT_OK bit which indicates the next WSAAsyncSelect
* call with FD_CONNECT set should send a message indicating the
* connection succeeded and then clear this bit.
*
* This is a hack to make asynchronous connect calls vaguely work as
* they should.
*/
sock->flags |= IPX_CONNECT_OK;
/* The TCP connection is up!
*
* Store the remote IPX address in remote_addr and mark the socket as
@ -2145,3 +2190,26 @@ SOCKET PASCAL accept(SOCKET s, struct sockaddr *addr, int *addrlen)
return r_accept(s, addr, addrlen);
}
}
int PASCAL WSAAsyncSelect(SOCKET s, HWND hWnd, unsigned int wMsg, long lEvent)
{
if(lEvent & FD_CONNECT)
{
ipx_socket *sock = get_socket(s);
if(sock)
{
if(sock->flags & IPX_CONNECT_OK)
{
log_printf(LOG_DEBUG, "Posting message %u for FD_CONNECT on socket %d", wMsg, sock->fd);
PostMessage(hWnd, wMsg, sock->fd, MAKEWORD(FD_CONNECT, 0));
sock->flags &= ~IPX_CONNECT_OK;
}
unlock_sockets();
}
}
return r_WSAAsyncSelect(s, hWnd, wMsg, lEvent);
}

View File

@ -29,7 +29,7 @@ getprotobynumber
getservbyname
getservbyport
gethostname
WSAAsyncSelect
WSAAsyncSelect:0
WSAAsyncGetHostByAddr
WSAAsyncGetHostByName
WSAAsyncGetProtoByNumber