NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/47408: sendto(2) issue with IPv6 UDP datagrams
>Number: 47408
>Category: kern
>Synopsis: sendto(2) issue with IPv6 UDP datagrams
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Jan 05 20:55:00 +0000 2013
>Originator: Anthony Mallet
>Release: 6.99.16, Thu Jan 3 14:14:16 CET 2013
>Organization:
>Environment:
NetBSD cactus 6.99.16 NetBSD 6.99.16 (CACTUS) #21: Thu Jan 3 14:14:16 CET 2013
>Description:
I'm fighting with pkgsrc/net/wide-dhcpv6. To make a long story short, I think I
finally isolated the issue, that I can reproduce with the attached test program.
It seems that, for any socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP), the second
sendto(2) call will fail with EISCONN, even though the socket is never
connected. Also, trying to explicitly connect the socket will fail. This does
not happen for AF_INET.
Here is the output of the attached test program. This is on a Jan 3 -current,
and I get the same results on another -current machine from Oct 20. I can
verify with tcpdump that the packets are correctly transmitted (or not). I
could test on a Linux machine and it worked fine.
ficus[~] > gcc -Wall -o sendto sendto.c
ficus[~] > ./sendto -4
sendto: 1st sendto: PASS
sendto: 2nd sendto: PASS
sendto: 1st connect: PASS
sendto: 1st send: PASS
sendto: 2nd connect: PASS
sendto: 2nd send: PASS
ficus[~] > ./sendto -6
sendto: 1st sendto: PASS
sendto: 2nd sendto: FAIL: Socket is already connected
sendto: 1st connect: FAIL: Socket is already connected
sendto: 1s send: FAIL: Destination address required
sendto: 2nd connect: FAIL: Socket is already connected
sendto: 2nd send: FAIL: Destination address required
ficus[~] >
>How-To-Repeat:
/* this is the sendto(2) test program */
#include <sys/socket.h>
#include <netinet/in.h>
#include <err.h>
#include <netdb.h>
#include <string.h>
int
main(int argc, const char *argv[])
{
struct addrinfo hints;
struct addrinfo *res;
const char msg[] = "sendto test";
int S, s;
int e;
/* lookup localhost addr, depending on argv[1] */
memset(&hints, 0, sizeof(hints));
if (argc > 1 && !strcmp("-6", argv[1]))
hints.ai_family = AF_INET6;
else
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
hints.ai_flags = 0;
e = getaddrinfo("localhost", "9999", &hints, &res);
if (e) errx(2, "getaddrinfo: %s", gai_strerror(e));
/* server socket */
S = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (S < 0) err(2, "server socket");
if (bind(S, res->ai_addr, res->ai_addrlen) < 0) err(2, "bind");
/* client socket */
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (s < 0) err(2, "client socket");
/* sendto */
e = sendto(s, msg, sizeof(msg), 0, res->ai_addr, res->ai_addrlen);
if (e != sizeof(msg))
warn("1s sendto: FAIL");
else
warnx("1st sendto: PASS");
e = sendto(s, msg, sizeof(msg), 0, res->ai_addr, res->ai_addrlen);
if (e != sizeof(msg))
warn("2nd sendto: FAIL");
else
warnx("2nd sendto: PASS");
/* connect + send */
e = connect(s, res->ai_addr, res->ai_addrlen);
if (e)
warn("1st connect: FAIL");
else
warnx("1st connect: PASS");
e = send(s, msg, sizeof(msg), 0);
if (e != sizeof(msg))
warn("1s send: FAIL");
else
warnx("1st send: PASS");
e = connect(s, res->ai_addr, res->ai_addrlen);
if (e)
warn("2nd connect: FAIL");
else
warnx("2nd connect: PASS");
e = send(s, msg, sizeof(msg), 0);
if (e != sizeof(msg))
warn("2nd send: FAIL");
else
warnx("2nd send: PASS");
return 0;
}
>Fix:
Home |
Main Index |
Thread Index |
Old Index