mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 15:32:35 +00:00
IP-SENDTO with pf=ip4 failed with "trailing garbage"
This commit is contained in:
parent
602a54420e
commit
bd727963a0
4 changed files with 53 additions and 71 deletions
4
CHANGES
4
CHANGES
|
@ -19,8 +19,8 @@ Corrections:
|
|||
did not work.
|
||||
Thanks to Linus Luessing for reporting this bug.
|
||||
|
||||
Up to version 1.8.0.0 IP-SENDTO and option pf (protocol-family) with
|
||||
protocol name (vs.numeric argument) failed with message:
|
||||
IP-SENDTO and option pf (protocol-family) with protocol name (vs.numeric
|
||||
argument) failed with message:
|
||||
E retropts_int(): trailing garbage in numerical arg of option "protocol-family"
|
||||
Test: IP_SENDTO_PF
|
||||
|
||||
|
|
|
@ -346,7 +346,7 @@ int sockaddr_vm_parse(struct sockaddr_vm *sa, const char *cid_str,
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif /* WITH_IP4 */
|
||||
#endif /* WITH_VSOCK */
|
||||
|
||||
#if !HAVE_INET_NTOP
|
||||
/* http://www.opengroup.org/onlinepubs/000095399/functions/inet_ntop.html */
|
||||
|
|
72
xio-ip.c
72
xio-ip.c
|
@ -393,16 +393,18 @@ int xiogetaddrinfo(const char *node, const char *service,
|
|||
ai_flags?ai_flags[0]:0, ai_flags?ai_flags[1]:0, res);
|
||||
if (service && service[0]=='\0') {
|
||||
Error("xiogetaddrinfo(): empty port and service");
|
||||
return EAI_NONAME;
|
||||
}
|
||||
|
||||
#if LATER
|
||||
#ifdef WITH_VSOCK
|
||||
if (family == AF_VSOCK) {
|
||||
error_num = sockaddr_vm_parse(&sau->vm, node, service);
|
||||
if (error_num < 0)
|
||||
return STAT_NORETRY;
|
||||
|
||||
return STAT_OK;
|
||||
if (error_num < 0) {
|
||||
errno = EINVAL;
|
||||
return EAI_SYSTEM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* WITH_VSOCK */
|
||||
#endif /* LATER */
|
||||
|
@ -457,7 +459,7 @@ int xiogetaddrinfo(const char *node, const char *service,
|
|||
#if WITH_IP6
|
||||
} else if (node && node[0] == '[' && node[(nodelen=strlen(node))-1]==']') {
|
||||
if ((numnode = Malloc(nodelen-1)) == NULL)
|
||||
return STAT_NORETRY;
|
||||
return EAI_MEMORY;
|
||||
|
||||
strncpy(numnode, node+1, nodelen-2); /* ok */
|
||||
numnode[nodelen-2] = '\0';
|
||||
|
@ -507,25 +509,19 @@ int xiogetaddrinfo(const char *node, const char *service,
|
|||
freeaddrinfo(*res);
|
||||
if (numnode)
|
||||
free(numnode);
|
||||
return STAT_NORETRY;
|
||||
return EAI_SERVICE;
|
||||
}
|
||||
/* Probably unsupported protocol (e.g. UDP-Lite), fallback to 0 */
|
||||
hints.ai_protocol = 0;
|
||||
continue;
|
||||
}
|
||||
if ((error_num = Getaddrinfo(node, service, &hints, res)) != 0) {
|
||||
Error7("getaddrinfo(\"%s\", \"%s\", {0x%02x,%d,%d,%d}, {}): %s",
|
||||
node?node:"NULL", service?service:"NULL",
|
||||
hints.ai_flags, hints.ai_family,
|
||||
hints.ai_socktype, hints.ai_protocol,
|
||||
(error_num == EAI_SYSTEM)?
|
||||
strerror(errno):gai_strerror(error_num));
|
||||
if (*res != NULL)
|
||||
freeaddrinfo(*res);
|
||||
if (numnode)
|
||||
free(numnode);
|
||||
|
||||
return STAT_RETRYLATER;
|
||||
return error_num;
|
||||
}
|
||||
} while (1);
|
||||
service = NULL; /* do not resolve later again */
|
||||
|
@ -645,12 +641,13 @@ int xiogetaddrinfo(const char *node, const char *service,
|
|||
|
||||
#else
|
||||
Error("no resolver function available");
|
||||
return STAT_NORETRY;
|
||||
errno = ENOSYS;
|
||||
return EAI_SYSTEM;
|
||||
#endif
|
||||
|
||||
if (numnode) free(numnode);
|
||||
|
||||
return STAT_OK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void xiofreeaddrinfo(struct addrinfo *res) {
|
||||
|
@ -668,11 +665,12 @@ void xiofreeaddrinfo(struct addrinfo *res) {
|
|||
|
||||
/* A simple resolver interface that just returns one address,
|
||||
the first found by calling xiogetaddrinfo().
|
||||
family may be AF_INET, AF_INET6, or AF_UNSPEC;
|
||||
Returns -1 when an error occurred or when no result found.
|
||||
pf may be AF_INET, AF_INET6, or AF_UNSPEC;
|
||||
on failure logs error message;
|
||||
returns STAT_OK, STAT_RETRYLATER, STAT_NORETRY
|
||||
*/
|
||||
int xioresolve(const char *node, const char *service,
|
||||
int family, int socktype, int protocol,
|
||||
int pf, int socktype, int protocol,
|
||||
union sockaddr_union *addr, socklen_t *addrlen,
|
||||
const int ai_flags[2])
|
||||
{
|
||||
|
@ -680,28 +678,38 @@ int xioresolve(const char *node, const char *service,
|
|||
struct addrinfo *aip;
|
||||
int rc;
|
||||
|
||||
rc = xiogetaddrinfo(node, service, family, socktype, protocol,
|
||||
rc = xiogetaddrinfo(node, service, pf, socktype, protocol,
|
||||
&res, ai_flags);
|
||||
if (rc != 0) {
|
||||
if (rc == EAI_AGAIN) {
|
||||
Warn3("xioresolve(node=\"%s\", pf=%d, ...): %s",
|
||||
node?node:"NULL", pf, gai_strerror(rc));
|
||||
xiofreeaddrinfo(res);
|
||||
return -1;
|
||||
return STAT_RETRYLATER;
|
||||
} else if (rc != 0) {
|
||||
Error3("xioresolve(node=\"%s\", pf=%d, ...): %s",
|
||||
node?node:"NULL", pf,
|
||||
(rc == EAI_SYSTEM)?strerror(errno):gai_strerror(rc));
|
||||
xiofreeaddrinfo(res);
|
||||
return STAT_NORETRY;
|
||||
}
|
||||
if (res == NULL) {
|
||||
Warn1("xioresolve(node=\"%s\", ...): No result", node);
|
||||
Error3("xioresolve(node=\"%s\", pf=%d, ...): %s",
|
||||
node?node:"NULL", pf, gai_strerror(EAI_NODATA));
|
||||
xiofreeaddrinfo(res);
|
||||
return -1;
|
||||
return STAT_NORETRY;
|
||||
}
|
||||
if (res->ai_addrlen > *addrlen) {
|
||||
Warn3("xioresolve(node=\"%s\", addrlen="F_socklen", ...): "F_socklen" bytes required", node, *addrlen, res->ai_addrlen);
|
||||
Error3("xioresolve(node=\"%s\", addrlen="F_socklen", ...): "F_socklen" bytes required",
|
||||
node, *addrlen, res->ai_addrlen);
|
||||
xiofreeaddrinfo(res);
|
||||
return -1;
|
||||
return STAT_NORETRY;
|
||||
}
|
||||
if (res->ai_next != NULL) {
|
||||
Info4("xioresolve(node=\"%s\", service=%s%s%s, ...): More than one address found", node?node:"NULL", service?"\"":"", service?service:"NULL", service?"\"":"");
|
||||
}
|
||||
|
||||
aip = res;
|
||||
if (ai_flags != NULL && ai_flags[0] & AI_PASSIVE && family == PF_UNSPEC) {
|
||||
if (ai_flags != NULL && ai_flags[0] & AI_PASSIVE && pf == PF_UNSPEC) {
|
||||
/* We select the first IPv6 address, if available,
|
||||
because this might accept IPv4 connections too */
|
||||
while (aip != NULL) {
|
||||
|
@ -711,12 +719,22 @@ int xioresolve(const char *node, const char *service,
|
|||
}
|
||||
if (aip == NULL)
|
||||
aip = res;
|
||||
} else if (pf == PF_UNSPEC && xioparms.preferred_ip != '0') {
|
||||
int prefip = PF_UNSPEC;
|
||||
xioinit_ip(&prefip, xioparms.preferred_ip);
|
||||
while (aip != NULL) {
|
||||
if (aip->ai_family == prefip)
|
||||
break;
|
||||
aip = aip->ai_next;
|
||||
}
|
||||
if (aip == NULL)
|
||||
aip = res;
|
||||
}
|
||||
|
||||
memcpy(addr, aip->ai_addr, aip->ai_addrlen);
|
||||
*addrlen = aip->ai_addrlen;
|
||||
xiofreeaddrinfo(res);
|
||||
return 0;
|
||||
return STAT_OK;
|
||||
}
|
||||
|
||||
#if defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA)
|
||||
|
|
46
xio-udp.c
46
xio-udp.c
|
@ -286,21 +286,8 @@ int xioopen_ipdgram_listen(
|
|||
}
|
||||
|
||||
xioinit_ip(&pf, xioparms.default_ip);
|
||||
if (pf == PF_UNSPEC) {
|
||||
#if WITH_IP4 && WITH_IP6
|
||||
switch (xioparms.default_ip) {
|
||||
case '4': pf = PF_INET; break;
|
||||
case '6': pf = PF_INET6; break;
|
||||
default: break; /* includes \0 */
|
||||
}
|
||||
#elif WITH_IP6
|
||||
pf = PF_INET6;
|
||||
#else
|
||||
pf = PF_INET;
|
||||
#endif
|
||||
}
|
||||
|
||||
retropt_socket_pf(opts, &pf);
|
||||
|
||||
retropt_int(opts, OPT_SO_PROTOTYPE, &ipproto);
|
||||
|
||||
if (applyopts_single(sfd, opts, PH_INIT) < 0)
|
||||
|
@ -460,6 +447,7 @@ int xioopen_udp_datagram(
|
|||
sfd->para.socket.ip.dosourceport = true;
|
||||
}
|
||||
|
||||
xioinit_ip(&pf, xioparms.default_ip);
|
||||
retropt_socket_pf(opts, &pf);
|
||||
|
||||
result =
|
||||
|
@ -535,23 +523,11 @@ int xioopen_udp_recvfrom(
|
|||
}
|
||||
|
||||
xioinit_ip(&pf, xioparms.default_ip);
|
||||
retropt_socket_pf(opts, &pf);
|
||||
|
||||
sfd->howtoend = END_NONE;
|
||||
if (sfd->howtoend == END_UNSPEC)
|
||||
sfd->howtoend = END_NONE;
|
||||
retropt_socket_pf(opts, &pf);
|
||||
if (pf == PF_UNSPEC) {
|
||||
#if WITH_IP4 && WITH_IP6
|
||||
switch (xioparms.default_ip) {
|
||||
case '4': pf = PF_INET; break;
|
||||
case '6': pf = PF_INET6; break;
|
||||
default: break; /* includes \0 */
|
||||
}
|
||||
#elif WITH_IP6
|
||||
pf = PF_INET6;
|
||||
#else
|
||||
pf = PF_INET;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Set AI_PASSIVE, except when it is explicitely disabled */
|
||||
ai_flags2[0] = xfd->stream.para.socket.ip.ai_flags[0];
|
||||
|
@ -626,20 +602,8 @@ int xioopen_udp_recv(
|
|||
return STAT_NORETRY;
|
||||
}
|
||||
|
||||
xioinit_ip(&pf, xioparms.default_ip);
|
||||
retropt_socket_pf(opts, &pf);
|
||||
if (pf == PF_UNSPEC) {
|
||||
#if WITH_IP4 && WITH_IP6
|
||||
switch (xioparms.default_ip) {
|
||||
case '4': pf = PF_INET; break;
|
||||
case '6': pf = PF_INET6; break;
|
||||
default: break; /* includes \0 */
|
||||
}
|
||||
#elif WITH_IP6
|
||||
pf = PF_INET6;
|
||||
#else
|
||||
pf = PF_INET;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Set AI_PASSIVE, except when it is explicitely disabled */
|
||||
ai_flags2[0] = xfd->stream.para.socket.ip.ai_flags[0];
|
||||
|
|
Loading…
Reference in a new issue