mirror of
https://github.com/solemnwarning/ipxwrapper
synced 2024-12-30 16:45:37 +01:00
Properly handle IPX socket descriptors used in select() writefds.
If any IPX sockets are passed to select() in the writefds set, substitute them for the private UDP socket before calling the real select(), if it remains in writefds upon return, remove it and restore the previously removed IPX sockets. In short: Allow detecting when an IPX socket is ready to send.
This commit is contained in:
parent
d7c9e10349
commit
493bc9358b
@ -21,3 +21,4 @@ EXPORTS
|
||||
listen
|
||||
accept
|
||||
WSAAsyncSelect
|
||||
select
|
||||
|
@ -188,5 +188,6 @@ 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);
|
||||
int PASCAL r_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timeval *timeout);
|
||||
|
||||
#endif /* !IPXWRAPPER_H */
|
||||
|
@ -7,7 +7,7 @@ htonl:4
|
||||
ntohl:4
|
||||
htons:4
|
||||
ntohs:4
|
||||
select:4
|
||||
r_select:4
|
||||
r_listen:4
|
||||
r_accept:4
|
||||
WSACreateEvent:4
|
||||
|
@ -1514,7 +1514,7 @@ int PASCAL ioctlsocket(SOCKET fd, long cmd, u_long *argp)
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(sock->fd, &fdset);
|
||||
|
||||
int r = select(1, &fdset, NULL, NULL, &tv);
|
||||
int r = r_select(1, &fdset, NULL, NULL, &tv);
|
||||
|
||||
if(r == -1)
|
||||
{
|
||||
@ -1779,7 +1779,7 @@ static int _connect_spx(ipx_socket *sock, struct sockaddr_ipx *ipxaddr)
|
||||
.tv_usec = ((wait_until - now) % 1000) * 1000
|
||||
};
|
||||
|
||||
if(select(1, &fdset, NULL, NULL, &tv) == -1)
|
||||
if(r_select(1, &fdset, NULL, NULL, &tv) == -1)
|
||||
{
|
||||
closesocket(lookup_fd);
|
||||
free(packet);
|
||||
@ -1892,7 +1892,7 @@ static int _connect_spx(ipx_socket *sock, struct sockaddr_ipx *ipxaddr)
|
||||
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))
|
||||
if(r_select(1, NULL, &w_fdset, &e_fdset, NULL) == 1 && FD_ISSET(sock->fd, &w_fdset))
|
||||
{
|
||||
goto CONNECTED;
|
||||
}
|
||||
@ -2374,3 +2374,76 @@ int PASCAL WSAAsyncSelect(SOCKET s, HWND hWnd, unsigned int wMsg, long lEvent)
|
||||
|
||||
return r_WSAAsyncSelect(s, hWnd, wMsg, lEvent);
|
||||
}
|
||||
|
||||
int PASCAL select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timeval *timeout)
|
||||
{
|
||||
if(ipx_use_pcap)
|
||||
{
|
||||
/* Can't do anything when using pcap since there isn't a socket
|
||||
* to wait on for sending.
|
||||
*/
|
||||
return r_select(nfds, readfds, writefds, exceptfds, timeout);
|
||||
}
|
||||
|
||||
bool writefds_bodge = false;
|
||||
|
||||
fd_set writefds_pulled;
|
||||
FD_ZERO(&writefds_pulled);
|
||||
|
||||
if(writefds != NULL)
|
||||
{
|
||||
/* Search for any IPX sockets being referenced in writefds... */
|
||||
lock_sockets();
|
||||
|
||||
ipx_socket *sock, *tmp;
|
||||
HASH_ITER(hh, sockets, sock, tmp)
|
||||
{
|
||||
if(!(sock->flags & IPX_IS_SPX) && FD_ISSET(sock->fd, writefds))
|
||||
{
|
||||
/* Found one! Remove it and stash it for later. */
|
||||
writefds_bodge = true;
|
||||
FD_SET(sock->fd, &writefds_pulled);
|
||||
FD_CLR(sock->fd, writefds);
|
||||
}
|
||||
}
|
||||
|
||||
unlock_sockets();
|
||||
}
|
||||
|
||||
if(writefds_bodge)
|
||||
{
|
||||
/* At least one IPX socket was removed from writefds, put the
|
||||
* private UDP socket there instead since that is what actually
|
||||
* matters for sending.
|
||||
*/
|
||||
FD_SET(private_socket, writefds);
|
||||
}
|
||||
|
||||
int sret = r_select(nfds, readfds, writefds, exceptfds, timeout);
|
||||
|
||||
if(sret > 0 && writefds_bodge && FD_ISSET(private_socket, writefds))
|
||||
{
|
||||
/* We munged writefds and private_socket is still there, take it
|
||||
* out and re-add any of the IPX sockets we removed earlier.
|
||||
*/
|
||||
|
||||
FD_CLR(private_socket, writefds);
|
||||
--sret;
|
||||
|
||||
lock_sockets();
|
||||
|
||||
ipx_socket *sock, *tmp;
|
||||
HASH_ITER(hh, sockets, sock, tmp)
|
||||
{
|
||||
if(FD_ISSET(sock->fd, &writefds_pulled))
|
||||
{
|
||||
FD_SET(sock->fd, writefds);
|
||||
++sret;
|
||||
}
|
||||
}
|
||||
|
||||
unlock_sockets();
|
||||
}
|
||||
|
||||
return sret;
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ ntohl
|
||||
ntohs
|
||||
recv:0
|
||||
recvfrom:0
|
||||
select
|
||||
select:0
|
||||
send:0
|
||||
sendto:0
|
||||
setsockopt:0
|
||||
|
Loading…
x
Reference in New Issue
Block a user