>Number: 181092 >Category: misc >Synopsis: Invoke the function sendmsg be hung. >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Aug 06 14:30:00 UTC 2013 >Closed-Date: >Last-Modified: >Originator: jell >Release: FreeBSD-9.1-RELEASE-i386 >Organization: jell >Environment: FreeBSD jell 9.1-RELEASE FreeBSD 9.1-RELEASE #0 r243826: Tue Dec 4 06:55:39 UTC 2012 r...@obrian.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC i386 >Description: I wrote a simple tools to create a INET6 RAW socket, and try to invoke the function "sendmsg" to send a message. And I found when the message size is 9210, the function "sendmsg" will be hung. >How-To-Repeat: 1. Compile my test code(in attachment) 2. config a ipv6 address like "5555::6/64" 3. Run my test tools as "./test 5555::7 9210" 4. The process "test" will be hung. >Fix:
Patch attached with submission follows: #include <stdio.h> #include <unistd.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <stdlib.h> #include <string.h> #include <errno.h> void set_addr(struct sockaddr *pAddr, int domain, char *pAddress, unsigned short port) { struct sockaddr_in *sin4 = NULL; struct sockaddr_in6 *sin6 = NULL; if (domain == AF_INET) { struct sockaddr_in *sin4 = (struct sockaddr_in *)pAddr; memset(sin4, 0, sizeof(struct sockaddr_in)); sin4->sin_family = AF_INET; sin4->sin_port = htons(port); if (pAddress == NULL) { sin4->sin_addr.s_addr = htonl(INADDR_ANY); } else { sin4->sin_addr.s_addr = inet_addr(pAddress); } } else { struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)pAddr; memset(sin6, 0, sizeof(struct sockaddr_in6)); sin6->sin6_family = AF_INET6; sin6->sin6_port = htons(port); if (pAddress == NULL) { sin6->sin6_addr = in6addr_any; } else { inet_pton(AF_INET6, pAddress, &sin6->sin6_addr); } } } void usage() { printf("usage:\n\t test ipv6_address send_size\ne.g.\n\ttest 2000:56::56 9183"); exit(0); } int main(int argc, char* argv[]) { int buffer_size = 9183; int s = -1; char *pTmpBuffer = NULL; int nRet = 0; struct sockaddr_in6 sin6; char *pAddress; static struct msghdr smsghdr; struct iovec iov[2]; static char *scmsg = 0; struct cmsghdr *scmsgp = 0; int ip6optlen = 0; int hoplimit = 200; if (argc >= 3) { pAddress = argv[1];/* get the IP address */ buffer_size = atoi(argv[2]); /* get the send buffer size */ if (buffer_size <= 0) { usage(); } } else { usage(); } s = socket(AF_INET6, SOCK_RAW, 3); if (s < 0) { perror("create socket error\n"); exit(-1); } pTmpBuffer = (char *)malloc(buffer_size); if (pTmpBuffer == NULL) { perror("malloc failed:"); exit(-1); } memset(pTmpBuffer, 0, buffer_size); memset(&smsghdr, 0, sizeof(smsghdr)); set_addr((struct sockaddr *)&sin6, AF_INET6, pAddress, 0); smsghdr.msg_name = (char *)&sin6; smsghdr.msg_namelen = sizeof(sin6); ip6optlen = CMSG_SPACE(sizeof(int)); scmsg = (char *)malloc(ip6optlen); smsghdr.msg_control = (caddr_t)scmsg; smsghdr.msg_controllen = ip6optlen; scmsgp = (struct cmsghdr *)scmsg; scmsgp->cmsg_len = CMSG_LEN(sizeof(int)); scmsgp->cmsg_level = IPPROTO_IPV6; scmsgp->cmsg_type = IPV6_HOPLIMIT; *(int *)(CMSG_DATA(scmsgp)) = hoplimit; scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp); memset(&iov, 0, sizeof(iov)); iov[0].iov_base = (char *)pTmpBuffer; iov[0].iov_len = buffer_size; smsghdr.msg_iov = iov; smsghdr.msg_iovlen = 1; nRet = sendmsg(s, &smsghdr, 0); free(pTmpBuffer); if (nRet < 0) { perror("sendmsg failed:"); exit(-1); } printf("success send size: %d bytes\n", nRet); return 0; } >Release-Note: >Audit-Trail: >Unformatted: _______________________________________________ freebsd-bugs@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"