Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit 259e499

Browse files
[[ Bug 19598 ]] Allow the same local port to be used for multiple connections on all platforms
On some platforms, the SO_REUSEADDR is insufficient to allow the same local port to be used for multiple connections. On these platforms, the SO_REUSEPORT option is now set. More info can be found here: http://stackoverflow.com/questions/14388706/socket-options-so-reuseaddr-and-so-reuseport-how-do-they-differ-do-they-mean-t/14388707#14388707 An assertion failure on socket read has also been fixed.
1 parent c3791ad commit 259e499

2 files changed

Lines changed: 22 additions & 1 deletion

File tree

docs/notes/bugfix-19598.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Cannot accept and open sockets using the same local port on certain platforms

engine/src/opensslsocket.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,17 @@ bool MCS_connect_socket(MCSocket *p_socket, struct sockaddr_in *p_addr)
720720
return false;
721721
}
722722

723+
#ifdef SO_REUSEPORT
724+
// some platforms also require the SO_REUSEPORT option to be set in order to use the same local port for multiple connections
725+
t_port_reuse = 1;
726+
if (setsockopt(p_socket->fd, SOL_SOCKET, SO_REUSEPORT, (const char *)&t_port_reuse, sizeof(t_port_reuse)) != 0)
727+
{
728+
p_socket->error = strclone("can't use the local port");
729+
p_socket->doclose();
730+
return false;
731+
}
732+
#endif
733+
723734
if (bind(p_socket->fd, (struct sockaddr *)&t_bind_addr, sizeof(struct sockaddr_in)) != 0)
724735
{
725736
p_socket->error = strclone("can't bind to local host and port");
@@ -1133,6 +1144,15 @@ MCSocket *MCS_accept(uint2 port, MCObject *object, MCNameRef message, Boolean da
11331144
int on = 1;
11341145
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
11351146

1147+
#ifdef SO_REUSEPORT
1148+
on = 1;
1149+
if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (const char *)&on, sizeof(on)) != 0)
1150+
{
1151+
MCresult->sets("can't reuse port");
1152+
return NULL;
1153+
}
1154+
#endif
1155+
11361156
mc_sockaddr_in_t addr;
11371157

11381158
memset((char *)&addr, 0, sizeof(addr));
@@ -1591,7 +1611,7 @@ void MCSocket::readsome()
15911611
MCAutoStringRef n;
15921612
MCNewAutoNameRef t_name;
15931613
/* UNCHECKED */ MCStringCreateMutable(strlen(t) + U2L, &n);
1594-
/* UNCHECKED */ MCStringAppendFormat(&n, "%s:%d", t, MCSwapInt16NetworkToHost(addr.sin_port));
1614+
/* UNCHECKED */ MCStringAppendFormat(*n, "%s:%d", t, MCSwapInt16NetworkToHost(addr.sin_port));
15951615
/* UNCHECKED */ MCNameCreate(*n, &t_name);
15961616
uindex_t index;
15971617
if (accepting && !IO_findsocket(*t_name, index))

0 commit comments

Comments
 (0)