On Sun, 4 Jun 2006 23:58:19 -0700 [EMAIL PROTECTED] wrote:
> http://bugzilla.kernel.org/show_bug.cgi?id=6646 > > Summary: UDP socket doesn't return to bound state after > association is dissolved by connect(..AF_UNSPEC) > Kernel Version: 2.6.12 > Status: NEW > Severity: high > Owner: [EMAIL PROTECTED] > Submitter: [EMAIL PROTECTED] > > > Most recent kernel where this bug did not occur: > Distribution: > Hardware Environment: > Software Environment: > Problem Description: > When disconnect a UDP socket, Linux kernel set local port to zero if the port > number comes from a implicit bind. Linux connect(2) man page reads: > "Generally, connection-based protocol sockets may successfully *connect* only > once; connectionless protocol sockets may use *connect* multiple times to > change > their association. Connectionless sockets may dissolve the association by > connecting to an address with the /sa_family/ member of *sockaddr* set to > *AF_UNSPEC*." > But dissolve the association should not impact the local binding, while > currently it does. In contrast, Unix variants like Solaris don't alter local > binding when disconnecting a UDP socket. > > Steps to reproduce: > Compile attached c file, and run it. You'll see local port number changed > after > a UDP socket disconnected. > > #include <errno.h> > #include <string.h> > #include <sys/types.h> > #include <sys/socket.h> > #include <netinet/in.h> > #include <net/if.h> > #include <netdb.h> > #include <arpa/inet.h> > #include <stdio.h> > #include <stdlib.h> > > #define SERV_PORT 12345 > > void print_local_addr(int s); > > int main(int argc, char** argv) > { > int sockfd; > struct sockaddr_in servaddr, cliaddr; > > if (argc != 2) { > printf("Usage: disconnect_udp <ipaddress>"); > exit(0); > } > > // creat a UDP socket which binds to a local address > sockfd = socket(AF_INET, SOCK_DGRAM, 0); > bzero(&cliaddr, sizeof(cliaddr)); > cliaddr.sin_family = AF_INET; > if (inet_pton(AF_INET, argv[1], &cliaddr.sin_addr) != 1) { > perror("inet_pton failed"); > } > bind(sockfd, (struct sockaddr *)&cliaddr, sizeof(cliaddr)); > > // connect this UDP socket > bzero(&servaddr, sizeof(servaddr)); > servaddr.sin_family = AF_INET; > servaddr.sin_port = htons(SERV_PORT); > if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) != 1) { > perror("inet_pton failed"); > } > if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) > { > perror("connect failed"); > } > print_local_addr(sockfd); > > // disconnect it > servaddr.sin_family = AF_UNSPEC; > if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) > { > perror("connect failed"); > } > print_local_addr(sockfd); > > close(sockfd); > } > > void print_local_addr(int s) > { > struct sockaddr_in localaddr; > socklen_t len = 0; > char temp[INET_ADDRSTRLEN]; > > len = sizeof(localaddr); > if (getsockname(s, (struct sockaddr *)&localaddr, &len) != 0) { > perror("getsockname failed"); > } > > inet_ntop(AF_INET, &localaddr.sin_addr, temp, INET_ADDRSTRLEN); > printf("Local binding: address=%s, port=%d\n", > temp, ntohs(localaddr.sin_port)); > } > > ------- You are receiving this mail because: ------- > You are on the CC list for the bug, or are watching someone who is. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html