From b8644635b3f5bec6b9cd575034a03020da7edb24 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 14 Jun 2007 15:05:13 +0000 Subject: checked in patch from tracker 1656382 to fix TTL for non-multicast svn path=/trunk/externals/OSCx/; revision=7777 --- src/htmsocket.c | 104 ++++++++++++++++++++++++++++++++++++++++++++------------ src/htmsocket.h | 2 +- src/sendOSC.c | 29 ++++++++++------ 3 files changed, 102 insertions(+), 33 deletions(-) diff --git a/src/htmsocket.c b/src/htmsocket.c index 858a4c7..3abd7f6 100644 --- a/src/htmsocket.c +++ b/src/htmsocket.c @@ -103,9 +103,29 @@ typedef struct int id; } desc; +int IsAddressMulticast(unsigned long address) +{ + unsigned long adr = ntohl(address); + unsigned char A = (unsigned char)((adr & 0xFF000000) >> 24); + unsigned char B = (unsigned char)((adr & 0xFF0000) >> 16); + unsigned char C = (unsigned char)((adr & 0xFF00) >> 8); + + if (A==224 && B==0 && C==0) { + // This multicast group range is reserved for routing + // information and not meant to be used by applications. + return -1; + } + + // This is the multicast group IP range + if (A>=224 && A<=239) + return 1; + + return 0; +} + /* open a socket for HTM communication to given host on given portnumber */ /* if host is 0 then UNIX protocol is used (i.e. local communication */ -void *OpenHTMSocket(char *host, int portnumber, unsigned char multicast_TTL) +void *OpenHTMSocket(char *host, int portnumber, short *multicast_TTL) { struct sockaddr_in cl_addr; #ifndef WIN32 @@ -233,16 +253,37 @@ void *OpenHTMSocket(char *host, int portnumber, unsigned char multicast_TTL) perror("setsockopt broadcast"); } - // set multicast Time-To-Live: ss - if(setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &multicast_TTL, sizeof(multicast_TTL)) == -1) { - perror("setsockopt TTL"); - } - - if(bind(sockfd, (struct sockaddr *) &cl_addr, sizeof(cl_addr)) < 0) { - perror("could not bind\n"); - closesocket(sockfd); - sockfd = -1; - } + // check if specified address is a multicast group: ss 2007 + int multicast = IsAddressMulticast(o->serv_addr.sin_addr.s_addr); + + if (multicast == -1) { + perror("Multicast group range 224.0.0.[0-255] is reserved.\n"); + *multicast_TTL = -2; + close(sockfd); + sockfd = -1; + } + else { + // set TTL according to whether we have a multicast group or not + if (multicast) { + if (*multicast_TTL<0) + *multicast_TTL = 1; + } else + *multicast_TTL = -1; + + // set multicast Time-To-Live only if it is a multicast group: ss 2007 + if(*multicast_TTL>=0) { + unsigned char ttl = (unsigned char)*multicast_TTL; + if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, + &ttl, sizeof(ttl)) == -1) + perror("setsockopt TTL"); + } + + if(bind(sockfd, (struct sockaddr *) &cl_addr, sizeof(cl_addr)) < 0) { + perror("could not bind\n"); + closesocket(sockfd); + sockfd = -1; + } + } } else { perror("unable to make socket\n");} #else @@ -259,16 +300,37 @@ void *OpenHTMSocket(char *host, int portnumber, unsigned char multicast_TTL) perror("setsockopt"); } - // set multicast Time-To-Live: ss 2006 - if(setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &multicast_TTL, sizeof(multicast_TTL)) == -1) { - perror("setsockopt TTL"); - } - - if(bind(sockfd, (struct sockaddr *) &cl_addr, sizeof(cl_addr)) < 0) { - perror("could not bind\n"); - close(sockfd); - sockfd = -1; - } + // check if specified address is a multicast group: ss 2007 + int multicast = IsAddressMulticast(o->serv_addr.sin_addr.s_addr); + + if (multicast == -1) { + perror("Multicast group range 224.0.0.[0-255] is reserved.\n"); + *multicast_TTL = -2; + close(sockfd); + sockfd = -1; + } + else { + // check if specified address is a multicast group: ss 2007 + if (multicast) { + if (*multicast_TTL<0) + *multicast_TTL = 1; + } else + *multicast_TTL = -1; + + // set multicast Time-To-Live only if it is a multicast group: ss 2007 + if(*multicast_TTL>=0) { + unsigned char ttl = (unsigned char)*multicast_TTL; + if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, + &ttl, sizeof(ttl)) == -1) + perror("setsockopt TTL"); + } + + if(bind(sockfd, (struct sockaddr *) &cl_addr, sizeof(cl_addr)) < 0) { + perror("could not bind\n"); + close(sockfd); + sockfd = -1; + } + } } else { perror("unable to make socket\n");} #endif diff --git a/src/htmsocket.h b/src/htmsocket.h index fcdeccc..685c1f7 100644 --- a/src/htmsocket.h +++ b/src/htmsocket.h @@ -38,7 +38,7 @@ typedef int bool; /* open a socket for HTM communication to given host on given portnumber */ /* if host is 0 then UNIX protocol is used (i.e. local communication) */ -void *OpenHTMSocket(char *host, int portnumber, unsigned char multicast_TTL); +void *OpenHTMSocket(char *host, int portnumber, short *multicast_TTL); /* send a buffer of data over htm socket, returns TRUE on success. Note that udp sends rarely fail. UNIX sends fail if a kernal buffer overflows */ diff --git a/src/sendOSC.c b/src/sendOSC.c index 3c99402..59e9335 100644 --- a/src/sendOSC.c +++ b/src/sendOSC.c @@ -192,7 +192,7 @@ static void sendOSC_connect(t_sendOSC *x, t_symbol *s, int argc, t_atom *argv) / float fportno=0; t_symbol *hostname; int portno = fportno; - unsigned char ttl=1; + short ttl=-1; char *protocolStr; /* create a socket */ @@ -211,7 +211,7 @@ static void sendOSC_connect(t_sendOSC *x, t_symbol *s, int argc, t_atom *argv) / if (argc >= 3) { if (argv[2].a_type==A_FLOAT) - ttl = (unsigned char)argv[2].a_w.w_float; + ttl = (short)(unsigned char)argv[2].a_w.w_float; else return; } @@ -219,9 +219,12 @@ static void sendOSC_connect(t_sendOSC *x, t_symbol *s, int argc, t_atom *argv) / // make sure handle is available if(x->x_htmsocket == 0) { - x->x_htmsocket = OpenHTMSocket(hostname->s_name, portno, ttl); - if (!x->x_htmsocket) - post("sendOSC: Couldn't open socket: "); + x->x_htmsocket = OpenHTMSocket(hostname->s_name, portno, &ttl); + if (!x->x_htmsocket) { + post("sendOSC: Couldn't open socket: "); + if (ttl==-2) + post("sendOSC: Multicast group range 224.0.0.[0-255] is reserved.\n"); + } else { switch (x->x_protocol) @@ -236,12 +239,16 @@ static void sendOSC_connect(t_sendOSC *x, t_symbol *s, int argc, t_atom *argv) / protocolStr = "unknown"; break; } - post("sendOSC: connected to port %s:%d (hSock=%d) protocol = %s ttl = %d", - hostname->s_name, portno, x->x_htmsocket, protocolStr, ttl); - outlet_float(x->x_obj.ob_outlet, 1); - } - } - else + if (ttl>=0) + post("sendOSC: connected to port %s:%d (hSock=%d) protocol = %s ttl = %d", + hostname->s_name, portno, x->x_htmsocket, protocolStr, ttl); + else + post("sendOSC: connected to port %s:%d (hSock=%d) protocol = %s", + hostname->s_name, portno, x->x_htmsocket, protocolStr); + outlet_float(x->x_obj.ob_outlet, 1); + } + } + else perror("call to sendOSC_connect() against unavailable socket handle"); } -- cgit v1.2.1