Merge pull request #13417 from ANR2ME/adhoc_socket

Fix Failed to Bind already used port issue on Android/Linux
This commit is contained in:
Henrik Rydgård 2020-09-12 10:40:29 +02:00 committed by GitHub
commit 6c9b9b54b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 27 additions and 12 deletions

View File

@ -1840,6 +1840,16 @@ int setSockNoSIGPIPE(int sock, int flag) {
return -1;
}
int setSockReuseAddrPort(int sock) {
int opt = 1;
// Should we set SO_BROADCAST too for SO_REUSEADDR to works like SO_REUSEPORT ?
// Set SO_REUSEPORT also when supported (ie. Android)
#if defined(SO_REUSEPORT)
setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (const char*)&opt, sizeof(opt));
#endif
return setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(opt));
}
#if !defined(TCP_KEEPIDLE)
#define TCP_KEEPIDLE TCP_KEEPALIVE //TCP_KEEPIDLE on Linux is equivalent to TCP_KEEPALIVE on macOS
#endif
@ -1938,8 +1948,8 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){
// (may not works in WinXP/2003 for IPv4 due to "Weak End System" model)
if (((uint8_t*)&g_adhocServerIP.in.sin_addr.s_addr)[0] == 0x7f) { // (serverIp.S_un.S_un_b.s_b1 == 0x7f)
int on = 1;
setsockopt(metasocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on));
setsockopt(metasocket, SOL_SOCKET, SO_DONTROUTE, (const char*)&on, sizeof(on));
setSockReuseAddrPort(metasocket);
g_localhostIP.in.sin_port = 0;
// Bind Local Address to Socket

View File

@ -1224,6 +1224,11 @@ int setSockNoDelay(int tcpsock, int flag);
*/
int setSockNoSIGPIPE(int sock, int flag);
/*
* Set Socket SO_REUSEADDR and SO_REUSEPORT when supported
*/
int setSockReuseAddrPort(int sock);
/*
* Set Socket KeepAlive (opt = SO_KEEPALIVE)
*/

View File

@ -1733,11 +1733,8 @@ void interrupt(int sig)
*/
void enable_address_reuse(int fd)
{
// Enable Value
int on = 1;
// Enable Port Reuse
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on));
setSockReuseAddrPort(fd);
}
/**

View File

@ -966,7 +966,7 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 u
setSockNoSIGPIPE(usocket, 1);
// Enable Port Re-use, this will allow binding to an already used port, but only one of them can read the data (shared receive buffer?)
setsockopt(usocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one));
setSockReuseAddrPort(usocket);
// Binding Information for local Port
sockaddr_in addr;
@ -2627,13 +2627,14 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac,
setSockNoSIGPIPE(tcpsocket, 1);
// Enable Port Re-use
setsockopt(tcpsocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one));
setSockReuseAddrPort(tcpsocket);
// Apply Default Send Timeout Settings to Socket
setSockTimeout(tcpsocket, SO_SNDTIMEO, rexmt_int);
// Disable Nagle Algo to send immediately. Or may be we shouldn't disable Nagle since there is PtpFlush function?
if (g_Config.bTCPNoDelay) setSockNoDelay(tcpsocket, 1);
if (g_Config.bTCPNoDelay)
setSockNoDelay(tcpsocket, 1);
// Binding Information for local Port
sockaddr_in addr;
@ -2736,10 +2737,11 @@ int AcceptPtpSocket(int ptpId, int newsocket, sockaddr_in& peeraddr, SceNetEther
setSockNoSIGPIPE(newsocket, 1);
// Enable Port Re-use
setsockopt(newsocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one));
setSockReuseAddrPort(newsocket);
// Disable Nagle Algo to send immediately. Or may be we shouldn't disable Nagle since there is PtpFlush function?
if (g_Config.bTCPNoDelay) setSockNoDelay(newsocket, 1);
if (g_Config.bTCPNoDelay)
setSockNoDelay(newsocket, 1);
// Local Address Information
sockaddr_in local;
@ -3123,13 +3125,14 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int
setSockNoSIGPIPE(tcpsocket, 1);
// Enable Port Re-use
setsockopt(tcpsocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one));
setSockReuseAddrPort(tcpsocket);
// Apply Default Receive Timeout Settings to Socket
setSockTimeout(tcpsocket, SO_RCVTIMEO, rexmt_int);
// Disable Nagle Algo to send immediately. Or may be we shouldn't disable Nagle since there is PtpFlush function?
if (g_Config.bTCPNoDelay) setSockNoDelay(tcpsocket, 1);
if (g_Config.bTCPNoDelay)
setSockNoDelay(tcpsocket, 1);
// Binding Information for local Port
sockaddr_in addr;