From nobody@FreeBSD.org  Tue Aug  6 14:26:26 2013
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1])
	(using TLSv1 with cipher ADH-AES256-SHA (256/256 bits))
	(No client certificate requested)
	by hub.freebsd.org (Postfix) with ESMTP id 70BFDC4A
	for <freebsd-gnats-submit@FreeBSD.org>; Tue,  6 Aug 2013 14:26:26 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from oldred.freebsd.org (oldred.freebsd.org [8.8.178.121])
	(using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
	(No client certificate requested)
	by mx1.freebsd.org (Postfix) with ESMTPS id 5E4762151
	for <freebsd-gnats-submit@FreeBSD.org>; Tue,  6 Aug 2013 14:26:26 +0000 (UTC)
Received: from oldred.freebsd.org ([127.0.1.6])
	by oldred.freebsd.org (8.14.5/8.14.7) with ESMTP id r76EQP0j048285
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 6 Aug 2013 14:26:25 GMT
	(envelope-from nobody@oldred.freebsd.org)
Received: (from nobody@localhost)
	by oldred.freebsd.org (8.14.5/8.14.5/Submit) id r76EQP8j048284;
	Tue, 6 Aug 2013 14:26:25 GMT
	(envelope-from nobody)
Message-Id: <201308061426.r76EQP8j048284@oldred.freebsd.org>
Date: Tue, 6 Aug 2013 14:26:25 GMT
From: jell <jelllove@126.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: Invoke the function sendmsg be hung.
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         181092
>Category:       kern
>Synopsis:       [libc] Invoking the function sendmsg(2) hangs with ipv6
>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:  Sun Aug 11 17:51:02 UTC 2013
>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   root@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:
