Set sockets as non-blocking in tcp.c and add blocking checks
Changes: - Added is_nonblocking flag to Descriptor structure in system.c - Implemented mock_fcntl (Linux) and mock_ioctlsocket (Windows) to handle setting sockets as non-blocking - Set all sockets as non-blocking in tcp.c: - Listen sockets in create_listen_socket() - Accepted sockets in tcp_translate_events() - Connecting sockets in tcp_connect() - Added checks in mock_accept(), mock_recv(), and mock_send() to abort the simulation if a socket would block but is not configured as non-blocking - This ensures proper non-blocking socket configuration and helps catch blocking socket errors during simulation
This commit is contained in:
@@ -30,6 +30,21 @@ static SOCKET create_listen_socket(string addr, uint16_t port)
|
||||
if (fd == INVALID_SOCKET)
|
||||
return INVALID_SOCKET;
|
||||
|
||||
// Set socket as non-blocking
|
||||
#ifdef _WIN32
|
||||
u_long mode = 1;
|
||||
if (sys_ioctlsocket(fd, FIONBIO, &mode) != 0) {
|
||||
CLOSE_SOCKET(fd);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
#else
|
||||
int flags = sys_fcntl(fd, F_GETFL, 0);
|
||||
if (flags < 0 || sys_fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
|
||||
CLOSE_SOCKET(fd);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
#endif
|
||||
|
||||
char tmp[1<<10];
|
||||
if (addr.len >= (int) sizeof(tmp))
|
||||
return INVALID_SOCKET;
|
||||
@@ -200,6 +215,20 @@ int tcp_translate_events(TCP *tcp, Event *events, void **contexts, struct pollfd
|
||||
|
||||
SOCKET new_fd = sys_accept(tcp->listen_fd, NULL, NULL);
|
||||
if (new_fd != INVALID_SOCKET) {
|
||||
// Set accepted socket as non-blocking
|
||||
#ifdef _WIN32
|
||||
u_long mode = 1;
|
||||
if (sys_ioctlsocket(new_fd, FIONBIO, &mode) != 0) {
|
||||
CLOSE_SOCKET(new_fd);
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
int flags = sys_fcntl(new_fd, F_GETFL, 0);
|
||||
if (flags < 0 || sys_fcntl(new_fd, F_SETFL, flags | O_NONBLOCK) < 0) {
|
||||
CLOSE_SOCKET(new_fd);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
events[num_events++] = (Event) { EVENT_CONNECT, tcp->num_conns };
|
||||
conn_init(&tcp->conns[tcp->num_conns++], new_fd, false);
|
||||
}
|
||||
@@ -304,6 +333,21 @@ int tcp_connect(TCP *tcp, Address addr, int tag, ByteQueue **output)
|
||||
if (fd == INVALID_SOCKET)
|
||||
return -1;
|
||||
|
||||
// Set socket as non-blocking
|
||||
#ifdef _WIN32
|
||||
u_long mode = 1;
|
||||
if (sys_ioctlsocket(fd, FIONBIO, &mode) != 0) {
|
||||
CLOSE_SOCKET(fd);
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
int flags = sys_fcntl(fd, F_GETFL, 0);
|
||||
if (flags < 0 || sys_fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
|
||||
CLOSE_SOCKET(fd);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int ret;
|
||||
if (addr.is_ipv4) {
|
||||
struct sockaddr_in buf;
|
||||
|
||||
Reference in New Issue
Block a user