mirror of
https://github.com/3proxy/3proxy.git
synced 2026-10-28 22:05:48 +08:00
Event loop on Windows: the wake connection only our own
Another local process could connect to the listening socket the wake connection is made over before ours, and be accepted instead, leaving the loop impossible to wake. Only the connection from our own socket is taken; another is closed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
835ce04295
commit
e250f98598
17
src/loop.c
17
src/loop.c
@ -61,6 +61,8 @@ static int wakeinit(struct loop *l){
|
|||||||
struct sockaddr_in sa;
|
struct sockaddr_in sa;
|
||||||
int len = sizeof(sa), one = 1;
|
int len = sizeof(sa), one = 1;
|
||||||
SOCKET ls = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP), a = INVALID_SOCKET, b = INVALID_SOCKET;
|
SOCKET ls = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP), a = INVALID_SOCKET, b = INVALID_SOCKET;
|
||||||
|
struct sockaddr_in mine, peer;
|
||||||
|
int tries;
|
||||||
|
|
||||||
if(ls == INVALID_SOCKET) return 1;
|
if(ls == INVALID_SOCKET) return 1;
|
||||||
memset(&sa, 0, sizeof(sa));
|
memset(&sa, 0, sizeof(sa));
|
||||||
@ -70,12 +72,25 @@ static int wakeinit(struct loop *l){
|
|||||||
getsockname(ls, (struct sockaddr *)&sa, &len) ||
|
getsockname(ls, (struct sockaddr *)&sa, &len) ||
|
||||||
(a = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET ||
|
(a = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET ||
|
||||||
connect(a, (struct sockaddr *)&sa, sizeof(sa)) ||
|
connect(a, (struct sockaddr *)&sa, sizeof(sa)) ||
|
||||||
(b = accept(ls, NULL, NULL)) == INVALID_SOCKET){
|
(len = sizeof(mine), getsockname(a, (struct sockaddr *)&mine, &len))){
|
||||||
if(a != INVALID_SOCKET) closesocket(a);
|
if(a != INVALID_SOCKET) closesocket(a);
|
||||||
closesocket(ls);
|
closesocket(ls);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
/* only our own connection: another process may have connected to the
|
||||||
|
listening socket first */
|
||||||
|
for(tries = 0; tries < 8; tries++){
|
||||||
|
len = sizeof(peer);
|
||||||
|
if((b = accept(ls, (struct sockaddr *)&peer, &len)) == INVALID_SOCKET) break;
|
||||||
|
if(peer.sin_port == mine.sin_port && peer.sin_addr.s_addr == mine.sin_addr.s_addr) break;
|
||||||
|
closesocket(b);
|
||||||
|
b = INVALID_SOCKET;
|
||||||
|
}
|
||||||
closesocket(ls);
|
closesocket(ls);
|
||||||
|
if(b == INVALID_SOCKET){
|
||||||
|
closesocket(a);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
setsockopt(a, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one));
|
setsockopt(a, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one));
|
||||||
setnonblock(a);
|
setnonblock(a);
|
||||||
setnonblock(b);
|
setnonblock(b);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user