Tcl Source Code

Check-in [d2d9d14de4]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Factor out creation of the -sockname and -peername lists from TcpGetOptionProc() to TcpHostPortList(). Make it robust against implementations of getnameinfo() that error out if reverse mapping fails instead of falling back to the numeric representation.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: d2d9d14de487497f19dc316e196571cc68a849ac
User & Date: max 2012-11-26 17:40:29
Context
2012-11-28
00:04
[3590483]: Some compilers cannot initialize with complex non-constants. check-in: 7d73c405e1 user: dkf tags: trunk
2012-11-27
21:09
3588687 Added cross checks so that [load]ed extension, [load]ing interp, and linked stubs library al... check-in: eb3b3c4f75 user: dgp tags: bug-3588687
2012-11-26
17:40
Factor out creation of the -sockname and -peername lists from TcpGetOptionProc() to TcpHostPortList(... check-in: d2d9d14de4 user: max tags: trunk
15:27
doc formatting goofs check-in: c6b4acb1a5 user: dgp tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ChangeLog.









1
2
3
4
5
6
7








2012-11-20  Donal K. Fellows  <[email protected]>

	* generic/tclBinary.c (BinaryDecode64): [Bug 3033307]: Corrected
	handling of trailing whitespace when decoding base64. Thanks to Anton
	Kovalenko for reporting, and Andy Goth for the fix and tests.

2012-11-19  Donal K. Fellows  <[email protected]>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2012-11-26  Reinhard Max  <[email protected]>

	* unix/tclUnixSock.c: Factor out creation of the -sockname and
	-peername lists from TcpGetOptionProc() to TcpHostPortList().
	Make it robust against implementations of getnameinfo() that error
	out if reverse mapping fails instead of falling back to the
	numeric representation.
	
2012-11-20  Donal K. Fellows  <[email protected]>

	* generic/tclBinary.c (BinaryDecode64): [Bug 3033307]: Corrected
	handling of trailing whitespace when decoding base64. Thanks to Anton
	Kovalenko for reporting, and Andy Goth for the fix and tests.

2012-11-19  Donal K. Fellows  <[email protected]>

Changes to unix/tclUnixSock.c.

623
624
625
626
627
628
629




































































630
631
632
633
634
635
636

    return errorCode;
}

/*
 *----------------------------------------------------------------------
 *




































































 * TcpGetOptionProc --
 *
 *	Computes an option value for a TCP socket based channel, or a list of
 *	all options and their values.
 *
 *	Note: This code is based on code contributed by John Haxby.
 *







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704

    return errorCode;
}

/*
 *----------------------------------------------------------------------
 *
 * TcpHostPortList --
 *
 *	This function is called by the -gethostname and -getpeername
 *	switches of TcpGetOptionProc() to add three list elements
 *	with the textual representation of the given address to the
 *	given DString.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Adds three elements do dsPtr
 *
 *----------------------------------------------------------------------
 */
static void
TcpHostPortList(
    Tcl_Interp *interp,
    Tcl_DString *dsPtr,
    address addr,
    socklen_t salen)
{
#define SUPPRESS_RDNS_VAR "::tcl::unsupported::noReverseDNS"
    char host[NI_MAXHOST], nhost[NI_MAXHOST], nport[NI_MAXSERV];
    int flags = 0;

    getnameinfo(&addr.sa, salen,
                nhost, sizeof(nhost), nport, sizeof(nport),
                NI_NUMERICHOST | NI_NUMERICSERV);
    Tcl_DStringAppendElement(dsPtr, nhost);
    /*
     * We don't want to resolve INADDR_ANY and sin6addr_any; they
     * can sometimes cause problems (and never have a name).
     */
    if (addr.sa.sa_family == AF_INET) {
        if (addr.sa4.sin_addr.s_addr == INADDR_ANY) {
            flags |= NI_NUMERICHOST;
        }
#ifndef NEED_FAKE_RFC2553
    } else if (addr.sa.sa_family == AF_INET6) {
        if ((IN6_ARE_ADDR_EQUAL(&addr.sa6.sin6_addr,
                                &in6addr_any))
            || (IN6_IS_ADDR_V4MAPPED(&addr.sa6.sin6_addr) &&
                addr.sa6.sin6_addr.s6_addr[12] == 0 &&
                addr.sa6.sin6_addr.s6_addr[13] == 0 &&
                addr.sa6.sin6_addr.s6_addr[14] == 0 &&
                addr.sa6.sin6_addr.s6_addr[15] == 0)) {
            flags |= NI_NUMERICHOST;
        }
#endif /* NEED_FAKE_RFC2553 */
    }
    /* Check if reverse DNS has been switched off globally */
    if (interp != NULL && Tcl_GetVar(interp, SUPPRESS_RDNS_VAR, 0) != NULL) {
        flags |= NI_NUMERICHOST;
    }
    if (getnameinfo(&addr.sa, salen, host, sizeof(host), NULL, 0, flags) == 0) {
        /* Reverse mapping worked */
        Tcl_DStringAppendElement(dsPtr, host);
    } else {
        /* Reverse mappong failed - use the numeric rep once more */
        Tcl_DStringAppendElement(dsPtr, nhost);
    }
    Tcl_DStringAppendElement(dsPtr, nport);
}

/*
 *----------------------------------------------------------------------
 *
 * TcpGetOptionProc --
 *
 *	Computes an option value for a TCP socket based channel, or a list of
 *	all options and their values.
 *
 *	Note: This code is based on code contributed by John Haxby.
 *
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
    const char *optionName,	/* Name of the option to retrieve the value
				 * for, or NULL to get all options and their
				 * values. */
    Tcl_DString *dsPtr)		/* Where to store the computed value;
				 * initialized by caller. */
{
    TcpState *statePtr = instanceData;
    char host[NI_MAXHOST], port[NI_MAXSERV];
    size_t len = 0;
    int reverseDNS = 0;
#define SUPPRESS_RDNS_VAR "::tcl::unsupported::noReverseDNS"

    if (optionName != NULL) {
	len = strlen(optionName);
    }

    if ((len > 1) && (optionName[1] == 'e') &&
	    (strncmp(optionName, "-error", len) == 0)) {







<

<
<







720
721
722
723
724
725
726

727


728
729
730
731
732
733
734
    const char *optionName,	/* Name of the option to retrieve the value
				 * for, or NULL to get all options and their
				 * values. */
    Tcl_DString *dsPtr)		/* Where to store the computed value;
				 * initialized by caller. */
{
    TcpState *statePtr = instanceData;

    size_t len = 0;



    if (optionName != NULL) {
	len = strlen(optionName);
    }

    if ((len > 1) && (optionName[1] == 'e') &&
	    (strncmp(optionName, "-error", len) == 0)) {
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
        }
	if (err != 0) {
	    Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(err), -1);
	}
	return TCL_OK;
    }

    if (interp != NULL && Tcl_GetVar(interp, SUPPRESS_RDNS_VAR, 0) != NULL) {
        reverseDNS = NI_NUMERICHOST;
    }
    
    if ((len == 0) || ((len > 1) && (optionName[1] == 'p') &&
	    (strncmp(optionName, "-peername", len) == 0))) {
        address peername;
        socklen_t size = sizeof(peername);

	if (getpeername(statePtr->fds.fd, &peername.sa, &size) >= 0) {
	    if (len == 0) {
		Tcl_DStringAppendElement(dsPtr, "-peername");
		Tcl_DStringStartSublist(dsPtr);
	    }
            
	    getnameinfo(&peername.sa, size, host, sizeof(host), NULL, 0,
                    NI_NUMERICHOST);
	    Tcl_DStringAppendElement(dsPtr, host);
	    getnameinfo(&peername.sa, size, host, sizeof(host), port,
                    sizeof(port), reverseDNS | NI_NUMERICSERV);
	    Tcl_DStringAppendElement(dsPtr, host);
	    Tcl_DStringAppendElement(dsPtr, port);
	    if (len) {
                return TCL_OK;
            }
            Tcl_DStringEndSublist(dsPtr);
	} else {
	    /*
	     * getpeername failed - but if we were asked for all the options







<
<
<
<










|
<
<
<
<
<
<
<







747
748
749
750
751
752
753




754
755
756
757
758
759
760
761
762
763
764







765
766
767
768
769
770
771
        }
	if (err != 0) {
	    Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(err), -1);
	}
	return TCL_OK;
    }





    if ((len == 0) || ((len > 1) && (optionName[1] == 'p') &&
	    (strncmp(optionName, "-peername", len) == 0))) {
        address peername;
        socklen_t size = sizeof(peername);

	if (getpeername(statePtr->fds.fd, &peername.sa, &size) >= 0) {
	    if (len == 0) {
		Tcl_DStringAppendElement(dsPtr, "-peername");
		Tcl_DStringStartSublist(dsPtr);
	    }
            TcpHostPortList(interp, dsPtr, peername, size);







	    if (len) {
                return TCL_OK;
            }
            Tcl_DStringEndSublist(dsPtr);
	} else {
	    /*
	     * getpeername failed - but if we were asked for all the options
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
	if (len == 0) {
	    Tcl_DStringAppendElement(dsPtr, "-sockname");
	    Tcl_DStringStartSublist(dsPtr);
	}
	for (fds = &statePtr->fds; fds != NULL; fds = fds->next) {
	    size = sizeof(sockname);
	    if (getsockname(fds->fd, &(sockname.sa), &size) >= 0) {
                int flags = reverseDNS;

		found = 1;
                getnameinfo(&sockname.sa, size, host, sizeof(host), NULL, 0,
                        NI_NUMERICHOST);
                Tcl_DStringAppendElement(dsPtr, host);

                /*
                 * We don't want to resolve INADDR_ANY and sin6addr_any; they
                 * can sometimes cause problems (and never have a name).
                 */

                flags |= NI_NUMERICSERV;
                if (sockname.sa.sa_family == AF_INET) {
                    if (sockname.sa4.sin_addr.s_addr == INADDR_ANY) {
                        flags |= NI_NUMERICHOST;
                    }
#ifndef NEED_FAKE_RFC2553
                } else if (sockname.sa.sa_family == AF_INET6) {
                    if ((IN6_ARE_ADDR_EQUAL(&sockname.sa6.sin6_addr,
                                &in6addr_any))
                        || (IN6_IS_ADDR_V4MAPPED(&sockname.sa6.sin6_addr) &&
                            sockname.sa6.sin6_addr.s6_addr[12] == 0 &&
                            sockname.sa6.sin6_addr.s6_addr[13] == 0 &&
                            sockname.sa6.sin6_addr.s6_addr[14] == 0 &&
                            sockname.sa6.sin6_addr.s6_addr[15] == 0)) {
                        flags |= NI_NUMERICHOST;
                    }
#endif /* NEED_FAKE_RFC2553 */
                }
		getnameinfo(&sockname.sa, size, host, sizeof(host), port,
                        sizeof(port), flags);
		Tcl_DStringAppendElement(dsPtr, host);
		Tcl_DStringAppendElement(dsPtr, port);
	    }
	}
        if (found) {
            if (len) {
                return TCL_OK;
            }
            Tcl_DStringEndSublist(dsPtr);







<
<

<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







795
796
797
798
799
800
801


802



803



























804
805
806
807
808
809
810
	if (len == 0) {
	    Tcl_DStringAppendElement(dsPtr, "-sockname");
	    Tcl_DStringStartSublist(dsPtr);
	}
	for (fds = &statePtr->fds; fds != NULL; fds = fds->next) {
	    size = sizeof(sockname);
	    if (getsockname(fds->fd, &(sockname.sa), &size) >= 0) {


		found = 1;



                TcpHostPortList(interp, dsPtr, sockname, size);



























	    }
	}
        if (found) {
            if (len) {
                return TCL_OK;
            }
            Tcl_DStringEndSublist(dsPtr);