Tcl UDP

Check-in [8afb0cd21c]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

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

Overview
Comment:Merging in multicast IF hack
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 8afb0cd21c429d3a7a42733a6a7903f15517ee9f
User & Date: hypnotoad 2014-08-29 15:17:28
Original User & Date: seandeelywoods 2014-08-29 15:17:28
Context
2014-09-08
15:58
Removed pkgIndex.tcl from cleanfiles check-in: 90b768a1b3 user: hypnotoad tags: trunk
2014-08-29
15:17
Merging in multicast IF hack check-in: 8afb0cd21c user: hypnotoad tags: trunk
15:01
Merging in updates from CVSHEAD check-in: 748bee8094 user: hypnotoad tags: trunk
2014-08-22
16:02
Typo fix Leaf check-in: d62a2a4f64 user: hypnotoad tags: mcastif
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/udp_tcl.c.

115
116
117
118
119
120
121

122
123
124
125
126
127
128
...
423
424
425
426
427
428
429

430
431
432
433
434
435
436
...
446
447
448
449
450
451
452

453
454
455
456
457
458
459
....
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054

1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
....
1502
1503
1504
1505
1506
1507
1508


1509
1510
1511
1512
1513
1514
1515
....
1763
1764
1765
1766
1767
1768
1769












































1770
1771
1772
1773
1774
1775
1776
                          const char *proto, int *portPtr);
static void udpTrace(const char *format, ...);
static int  udpGetService(Tcl_Interp *interp, const char *service,
                          unsigned short *servicePort);
static Tcl_Obj *ErrorToObj(const char * prefix);
static int hasOption(int argc, CONST84 char * argv[],const char* option );
static int udpSetRemoteOption(UdpState* statePtr, Tcl_Interp *interp, CONST84 char *newValue);

static int udpSetMulticastAddOption(UdpState* statePtr, Tcl_Interp *interp, CONST84 char *newValue);
static int udpSetMulticastDropOption(UdpState* statePtr, Tcl_Interp *interp, CONST84 char *newValue);
static int udpSetBroadcastOption(UdpState* statePtr, Tcl_Interp *interp, CONST84 char *newValue);
static int udpGetBroadcastOption(UdpState* statePtr, Tcl_Interp *interp, int* value);
static int udpSetMcastloopOption(UdpState* statePtr, Tcl_Interp *interp, CONST84 char *newValue);
static int udpGetMcastloopOption(UdpState *statePtr, Tcl_Interp *interp, unsigned char * value);
static int udpSetTtlOption(UdpState* statePtr, Tcl_Interp *interp, CONST84 char *newValue);
................................................................................
		"udp_conf fileId [-mcastadd] [-mcastdrop] groupaddr | "
#ifdef WIN32
		"udp_conf fileId [-mcastadd] [-mcastdrop] \"groupaddr netwif_index\" | "
#else
		"udp_conf fileId [-mcastadd] [-mcastdrop] \"groupaddr netwif\" | "
#endif
		"udp_conf fileId remotehost remoteport | "

		"udp_conf fileId [-myport] [-remote] [-peer] [-mcastgroups] [-mcastloop] [-broadcast] [-ttl]";
	
	if (argc >= 2) {
		chan = Tcl_GetChannel(interp, (char *)argv[1], NULL);
		if (chan != (Tcl_Channel) NULL) {
			statePtr = (UdpState *) Tcl_GetChannelInstanceData(chan);
		}
................................................................................
	}
	
	if (argc == 4 && statePtr != NULL) {
		if (hasOption(argc,argv,"-mcastloop") ||
			hasOption(argc,argv,"-broadcast") ||
			hasOption(argc,argv,"-mcastadd") ||
			hasOption(argc,argv,"-mcastdrop") ||

			hasOption(argc,argv,"-ttl")) { 
			r = Tcl_SetChannelOption(interp, statePtr->channel, argv[2], argv[3]);
		} else {
			sprintf(remoteOptions, "%s %s",argv[2],argv[3] );
			r = Tcl_SetChannelOption(interp, statePtr->channel, "-remote", remoteOptions);
		}
	}
................................................................................
		freeaddrinfo(result);

		sendaddrv6.sin6_family = AF_INET6;
		sendaddrv6.sin6_port = statePtr->remoteport;

		written = sendto(statePtr->sock, buf, toWrite, 0, (struct sockaddr *)&sendaddrv6, socksize);
	} else {
		socksize = sizeof(sendaddrv4);
		memset(&sendaddrv4, 0, socksize);
        sendaddrv4.sin_addr.s_addr = inet_addr(statePtr->remotehost);

        if (sendaddrv4.sin_addr.s_addr == -1) {
            name = gethostbyname(statePtr->remotehost);
			if (name == NULL) {
				UDPTRACE("UDP error - gethostbyname");
				return -1;
			}
			memcpy(&sendaddrv4.sin_addr, name->h_addr, sizeof(sendaddrv4.sin_addr));
		}


		sendaddrv4.sin_family = AF_INET;
		sendaddrv4.sin_port = statePtr->remoteport;

		written = sendto(statePtr->sock, buf, toWrite, 0, (struct sockaddr *)&sendaddrv4, socksize);
	}

	if (written < 0) {
		UDPTRACE("UDP error - sendto");
		return -1;
	}

................................................................................
{
    UdpState *statePtr = (UdpState *)instanceData;
    CONST84 char * options = "remote mcastadd mcastdrop mcastloop broadcast ttl";
    int r = TCL_OK;
	
    if (!strcmp("-remote", optionName)) {
		r = udpSetRemoteOption(statePtr,interp,(const char *)newValue);


    } else if (!strcmp("-mcastadd", optionName)) {
		r = udpSetMulticastAddOption(statePtr, interp, (const char *)newValue);		
    } else if (!strcmp("-mcastdrop", optionName)) {
		r = udpSetMulticastDropOption(statePtr, interp, (const char *)newValue);				
    } else if (!strcmp("-broadcast", optionName)) {
		r = udpSetBroadcastOption(statePtr, interp, (const char*) newValue);		
     } else if (!strcmp("-mcastloop", optionName)) {
................................................................................
	} else {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(newValue,-1));
	}

	return result;
}













































/*
 * ----------------------------------------------------------------------
 * udpSetMulticastAddOption --
 *
 *  Handle multicast add configuration requests.
 *
 * ----------------------------------------------------------------------






>







 







>







 







>







 







|
|
|

|

|
|
|
|
|
|
>
|
|
|
<
|







 







>
>







 







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







115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
...
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
...
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
....
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061

1062
1063
1064
1065
1066
1067
1068
1069
....
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
....
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
                          const char *proto, int *portPtr);
static void udpTrace(const char *format, ...);
static int  udpGetService(Tcl_Interp *interp, const char *service,
                          unsigned short *servicePort);
static Tcl_Obj *ErrorToObj(const char * prefix);
static int hasOption(int argc, CONST84 char * argv[],const char* option );
static int udpSetRemoteOption(UdpState* statePtr, Tcl_Interp *interp, CONST84 char *newValue);
static int udpSetMulticastIFOption(UdpState* statePtr, Tcl_Interp *interp, CONST84 char *newValue);
static int udpSetMulticastAddOption(UdpState* statePtr, Tcl_Interp *interp, CONST84 char *newValue);
static int udpSetMulticastDropOption(UdpState* statePtr, Tcl_Interp *interp, CONST84 char *newValue);
static int udpSetBroadcastOption(UdpState* statePtr, Tcl_Interp *interp, CONST84 char *newValue);
static int udpGetBroadcastOption(UdpState* statePtr, Tcl_Interp *interp, int* value);
static int udpSetMcastloopOption(UdpState* statePtr, Tcl_Interp *interp, CONST84 char *newValue);
static int udpGetMcastloopOption(UdpState *statePtr, Tcl_Interp *interp, unsigned char * value);
static int udpSetTtlOption(UdpState* statePtr, Tcl_Interp *interp, CONST84 char *newValue);
................................................................................
		"udp_conf fileId [-mcastadd] [-mcastdrop] groupaddr | "
#ifdef WIN32
		"udp_conf fileId [-mcastadd] [-mcastdrop] \"groupaddr netwif_index\" | "
#else
		"udp_conf fileId [-mcastadd] [-mcastdrop] \"groupaddr netwif\" | "
#endif
		"udp_conf fileId remotehost remoteport | "
		"udp_conf fileId -mcastif ipaddr | "
		"udp_conf fileId [-myport] [-remote] [-peer] [-mcastgroups] [-mcastloop] [-broadcast] [-ttl]";
	
	if (argc >= 2) {
		chan = Tcl_GetChannel(interp, (char *)argv[1], NULL);
		if (chan != (Tcl_Channel) NULL) {
			statePtr = (UdpState *) Tcl_GetChannelInstanceData(chan);
		}
................................................................................
	}
	
	if (argc == 4 && statePtr != NULL) {
		if (hasOption(argc,argv,"-mcastloop") ||
			hasOption(argc,argv,"-broadcast") ||
			hasOption(argc,argv,"-mcastadd") ||
			hasOption(argc,argv,"-mcastdrop") ||
			hasOption(argc,argv,"-mcastif") ||
			hasOption(argc,argv,"-ttl")) { 
			r = Tcl_SetChannelOption(interp, statePtr->channel, argv[2], argv[3]);
		} else {
			sprintf(remoteOptions, "%s %s",argv[2],argv[3] );
			r = Tcl_SetChannelOption(interp, statePtr->channel, "-remote", remoteOptions);
		}
	}
................................................................................
		freeaddrinfo(result);

		sendaddrv6.sin6_family = AF_INET6;
		sendaddrv6.sin6_port = statePtr->remoteport;

		written = sendto(statePtr->sock, buf, toWrite, 0, (struct sockaddr *)&sendaddrv6, socksize);
	} else {
          socksize = sizeof(sendaddrv4);
          memset(&sendaddrv4, 0, socksize);
          struct in_addr remote_addr;

          if(inet_aton(statePtr->remotehost,&remote_addr)==0) {
            name = gethostbyname(statePtr->remotehost);
            if (name == NULL) {
              UDPTRACE("UDP error - gethostbyname");
              return -1;
            }
            memcpy(&sendaddrv4.sin_addr, name->h_addr, sizeof(sendaddrv4.sin_addr));
          } else {
            sendaddrv4.sin_addr=remote_addr;
          }
          sendaddrv4.sin_family = AF_INET;
          sendaddrv4.sin_port = statePtr->remoteport;

          written = sendto(statePtr->sock, buf, toWrite, 0, (struct sockaddr *)&sendaddrv4, socksize);
	}

	if (written < 0) {
		UDPTRACE("UDP error - sendto");
		return -1;
	}

................................................................................
{
    UdpState *statePtr = (UdpState *)instanceData;
    CONST84 char * options = "remote mcastadd mcastdrop mcastloop broadcast ttl";
    int r = TCL_OK;
	
    if (!strcmp("-remote", optionName)) {
		r = udpSetRemoteOption(statePtr,interp,(const char *)newValue);
    } else if (!strcmp("-mcastif", optionName)) {
		r = udpSetMulticastIFOption(statePtr,interp,(const char *)newValue);                
    } else if (!strcmp("-mcastadd", optionName)) {
		r = udpSetMulticastAddOption(statePtr, interp, (const char *)newValue);		
    } else if (!strcmp("-mcastdrop", optionName)) {
		r = udpSetMulticastDropOption(statePtr, interp, (const char *)newValue);				
    } else if (!strcmp("-broadcast", optionName)) {
		r = udpSetBroadcastOption(statePtr, interp, (const char*) newValue);		
     } else if (!strcmp("-mcastloop", optionName)) {
................................................................................
	} else {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(newValue,-1));
	}

	return result;
}


/*
 * ----------------------------------------------------------------------
 * udpSetMulticastIFOption --
 *
 *  Specify the default gateway interface for multicast
 *
 * ----------------------------------------------------------------------
 */
static int
udpSetMulticastIFOption(UdpState *statePtr, Tcl_Interp *interp,CONST84 char *newValue)
{
  if (statePtr->ss_family == AF_INET) {
    struct in_addr interface_addr;
    if(inet_aton(newValue,&interface_addr)==0) {
      if (interp != NULL) {
        Tcl_SetObjResult(interp, ErrorToObj("error setting -mcastif (bad IP)"));
      }
      return TCL_ERROR;
    }
    if (setsockopt(statePtr->sock, IPPROTO_IP, IP_MULTICAST_IF, (const char*)&interface_addr, sizeof(interface_addr)) < 0) {
      if (interp != NULL) {
        Tcl_SetObjResult(interp, ErrorToObj("error setting -mcastif"));
      }
      return TCL_ERROR;
    }		
  } else {
    struct in6_addr interface_addr;
    if(inet_pton(AF_INET6,newValue,&interface_addr)==0) {
      if (interp != NULL) {
        Tcl_SetObjResult(interp, ErrorToObj("error setting -mcastif (bad IP)"));
      }
      return TCL_ERROR;
    }
    if (setsockopt(statePtr->sock, IPPROTO_IP, IPV6_MULTICAST_IF, (const char*)&interface_addr, sizeof(interface_addr)) < 0) {
      if (interp != NULL) {
        Tcl_SetObjResult(interp, ErrorToObj("error setting -mcastif"));
      }
      return TCL_ERROR;
    }
  }
  return TCL_OK;
}

/*
 * ----------------------------------------------------------------------
 * udpSetMulticastAddOption --
 *
 *  Handle multicast add configuration requests.
 *
 * ----------------------------------------------------------------------