mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 23:42:34 +00:00
Prevent error loop on RECVFROM addresses with fork
This commit is contained in:
parent
10680c8aad
commit
ff8de6c5cd
3 changed files with 27 additions and 3 deletions
7
CHANGES
7
CHANGES
|
@ -43,6 +43,13 @@ Corrections:
|
||||||
is now increased to 2047 bytes.
|
is now increased to 2047 bytes.
|
||||||
Change suggested by Mario Camou.
|
Change suggested by Mario Camou.
|
||||||
|
|
||||||
|
Addresses of type RECVFROM with option fork looped with an error
|
||||||
|
message in case that the second address failed before consuming the
|
||||||
|
packet. The fix makes RECVFROM drop the packet when the second address
|
||||||
|
failed before reading it. Use retry or forever option with the second
|
||||||
|
address if you want to avoid data loss.
|
||||||
|
Thanks to Chunmei Xu for reporting this issue and proving the patch.
|
||||||
|
|
||||||
Porting:
|
Porting:
|
||||||
In gcc version 10 the default changed from -fcommon to -fno-common.
|
In gcc version 10 the default changed from -fcommon to -fno-common.
|
||||||
Consequently, linking filan and procan failed with error
|
Consequently, linking filan and procan failed with error
|
||||||
|
|
14
doc/socat.yo
14
doc/socat.yo
|
@ -419,6 +419,7 @@ label(ADDRESS_IP_RECVFROM)dit(bf(tt(IP-RECVFROM:<protocol>)))
|
||||||
This address works well with IP-SENDTO address peers (see above).
|
This address works well with IP-SENDTO address peers (see above).
|
||||||
Protocol 255 uses the raw socket with the IP header being part of the
|
Protocol 255 uses the raw socket with the IP header being part of the
|
||||||
data.nl()
|
data.nl()
|
||||||
|
See the link(note about RECVFROM addresses)(NOTE_RECVFROM).nl()
|
||||||
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE) nl()
|
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE) nl()
|
||||||
Useful options:
|
Useful options:
|
||||||
link(pf)(OPTION_PROTOCOL_FAMILY),
|
link(pf)(OPTION_PROTOCOL_FAMILY),
|
||||||
|
@ -790,6 +791,7 @@ label(ADDRESS_SOCKET_RECVFROM)dit(bf(tt(SOCKET-RECVFROM:<domain>:<type>:<protoco
|
||||||
to find the appropriate values. The local-address must be the
|
to find the appropriate values. The local-address must be the
|
||||||
link(data)(TYPE_DATA) representation of a sockaddr structure without
|
link(data)(TYPE_DATA) representation of a sockaddr structure without
|
||||||
sa_family and (BSD) sa_len components.nl()
|
sa_family and (BSD) sa_len components.nl()
|
||||||
|
See the link(note about RECVFROM addresses)(NOTE_RECVFROM).nl()
|
||||||
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE)nl()
|
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE)nl()
|
||||||
Useful options:
|
Useful options:
|
||||||
link(fork)(OPTION_FORK),
|
link(fork)(OPTION_FORK),
|
||||||
|
@ -1113,11 +1115,15 @@ label(ADDRESS_UDP_RECVFROM)dit(bf(tt(UDP-RECVFROM:<port>)))
|
||||||
UDP/IP version 4 or 6
|
UDP/IP version 4 or 6
|
||||||
depending on option link(pf)(OPTION_PROTOCOL_FAMILY).
|
depending on option link(pf)(OPTION_PROTOCOL_FAMILY).
|
||||||
It receives one packet from an unspecified peer and may send one or more
|
It receives one packet from an unspecified peer and may send one or more
|
||||||
answer packets to that peer. This mode is particularly useful with fork
|
answer packets to that peer. This mode is particularly useful with
|
||||||
option
|
link(fork)(OPTION_FORK) option
|
||||||
where each arriving packet - from arbitrary peers - is handled by its own sub
|
where each arriving packet - from arbitrary peers - is handled by its own sub
|
||||||
process. This allows a behaviour similar to typical UDP based servers like ntpd
|
process. This allows a behaviour similar to typical UDP based servers like ntpd
|
||||||
or named. This address works well with socat UDP-SENDTO address peers.nl()
|
or named. This address works well with socat UDP-SENDTO address peers.nl()
|
||||||
|
label(NOTE_RECVFROM)Note: When the second address fails before entering the transfer loop the
|
||||||
|
packet is dropped. Use option link(retry)(OPTION_RETRY) or
|
||||||
|
link(forever)(OPTION_FOREVER) on the second address to avoid data loss.
|
||||||
|
nl()
|
||||||
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE) nl()
|
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE) nl()
|
||||||
Useful options:
|
Useful options:
|
||||||
link(fork)(OPTION_FORK),
|
link(fork)(OPTION_FORK),
|
||||||
|
@ -1233,6 +1239,7 @@ label(ADDRESS_UNIX_RECVFROM)dit(bf(tt(UNIX-RECVFROM:<filename>)))
|
||||||
This mode is particularly useful with fork option where each arriving packet - from arbitrary peers - is handled by its own sub process.
|
This mode is particularly useful with fork option where each arriving packet - from arbitrary peers - is handled by its own sub process.
|
||||||
This address works well with socat UNIX-SENDTO address peers.nl()
|
This address works well with socat UNIX-SENDTO address peers.nl()
|
||||||
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(NAMED)(GROUP_NAMED),link(CHILD)(GROUP_CHILD),link(UNIX)(GROUP_SOCK_UNIX) nl()
|
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(NAMED)(GROUP_NAMED),link(CHILD)(GROUP_CHILD),link(UNIX)(GROUP_SOCK_UNIX) nl()
|
||||||
|
See the link(note about RECVFROM addresses)(NOTE_RECVFROM).nl()
|
||||||
Useful options:
|
Useful options:
|
||||||
link(fork)(OPTION_FORK)nl()
|
link(fork)(OPTION_FORK)nl()
|
||||||
See also:
|
See also:
|
||||||
|
@ -2310,7 +2317,8 @@ label(OPTION_FORK)dit(bf(tt(fork)))
|
||||||
child:
|
child:
|
||||||
OPENSSL-LISTEN forks em(before) the SSL handshake, while OPENSSL-CONNECT
|
OPENSSL-LISTEN forks em(before) the SSL handshake, while OPENSSL-CONNECT
|
||||||
forks em(afterwards).
|
forks em(afterwards).
|
||||||
RETRY and FOREVER options are not inherited by the child process.nl()
|
link(retry)(OPTION_RETRY) and link(forever)(OPTION_FOREVER) options are not
|
||||||
|
inherited by the child process.nl()
|
||||||
On some operating systems (e.g. FreeBSD) this option does not work for
|
On some operating systems (e.g. FreeBSD) this option does not work for
|
||||||
UDP-LISTEN addresses.nl()
|
UDP-LISTEN addresses.nl()
|
||||||
enddit()
|
enddit()
|
||||||
|
|
|
@ -1128,6 +1128,8 @@ static pid_t xio_waitingfor; /* info from recv loop to signal handler:
|
||||||
that should send us the USR1 signal */
|
that should send us the USR1 signal */
|
||||||
static bool xio_hashappened; /* info from signal handler to loop: child
|
static bool xio_hashappened; /* info from signal handler to loop: child
|
||||||
process has read ("consumed") the packet */
|
process has read ("consumed") the packet */
|
||||||
|
static int xio_childstatus;
|
||||||
|
|
||||||
/* this is the signal handler for USR1 and CHLD */
|
/* this is the signal handler for USR1 and CHLD */
|
||||||
void xiosigaction_hasread(int signum
|
void xiosigaction_hasread(int signum
|
||||||
#if HAVE_STRUCT_SIGACTION_SA_SIGACTION && defined(SA_SIGINFO)
|
#if HAVE_STRUCT_SIGACTION_SA_SIGACTION && defined(SA_SIGINFO)
|
||||||
|
@ -1179,6 +1181,7 @@ void xiosigaction_hasread(int signum
|
||||||
}
|
}
|
||||||
if (pid == xio_waitingfor) {
|
if (pid == xio_waitingfor) {
|
||||||
xio_hashappened = true;
|
xio_hashappened = true;
|
||||||
|
xio_childstatus = WEXITSTATUS(status);
|
||||||
Debug("xiosigaction_hasread() ->");
|
Debug("xiosigaction_hasread() ->");
|
||||||
diag_in_handler = 0;
|
diag_in_handler = 0;
|
||||||
errno = _errno;
|
errno = _errno;
|
||||||
|
@ -1480,6 +1483,12 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
|
||||||
xio_waitingfor = 0; /* so this child will not set hashappened again */
|
xio_waitingfor = 0; /* so this child will not set hashappened again */
|
||||||
xio_hashappened = false;
|
xio_hashappened = false;
|
||||||
|
|
||||||
|
if (xio_childstatus != 0) {
|
||||||
|
char buff[512];
|
||||||
|
Recv(xfd->fd, buff, sizeof(buff), 0);
|
||||||
|
xio_childstatus = 0;
|
||||||
|
Info("drop data because of child exit failed");
|
||||||
|
}
|
||||||
Info("continue listening");
|
Info("continue listening");
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue