Hello Nick,

Could you test out the attached patch for the advertised interfaces? Example of module configuration:

modparam("stun", "primary_ip", "192.168.2.133 /  46.78.50.64")
modparam("stun", "primary_port", "5060    /   5061")
modparam("stun", "alternate_ip", "192.168.2.134 / 50.64.46.78")
modparam("stun", "alternate_port", "6001  /  6003")

Best regards,

Liviu Chircu
OpenSIPS Developer
http://www.opensips-solutions.com

On 02/19/2014 07:35 PM, Nick Altmann wrote:
Thank you. This code needed to run STUN on always NATed servers like Amazon cloud.

--
Nick


2014-02-19 21:32 GMT+04:00 Bogdan-Andrei Iancu <[email protected] <mailto:[email protected]>>:

    Hi,

    I identify the code that need to be changed - it should be a lot
    of work to add an "advertised" value for the configured IPs and
    ports. It should make it in the new release.

    Regards,

    Bogdan-Andrei Iancu
    OpenSIPS Founder and Developer
    http://www.opensips-solutions.com

    On 19.02.2014 17:45, Nick Altmann wrote:
    Yes, it is!

    --
    Nick


    2014-02-19 17:19 GMT+04:00 Bogdan-Andrei Iancu
    <[email protected] <mailto:[email protected]>>:

        Hi,

        Nick, you want something like an "advertised" but for the
        STUN stuff ?

        Regards,

        Bogdan-Andrei Iancu
        OpenSIPS Founder and Developer
        http://www.opensips-solutions.com

        On 19.02.2014 14:25, Nick Altmann wrote:
        I'm about STUN only. Its required two external IPs.
        I'm not about routing.

        --
        Nick


        2014-02-19 16:14 GMT+04:00 Ali Pey <[email protected]
        <mailto:[email protected]>>:

            Hi Nick,

            I don't think such a thing is possible in opensips.
            There can only be one advertised_address as far as I
            know. I think you need to do your own message
            manipulation in your route script based on the route
            it's going to.

            I'm interested in this scenario as well and look forward
            to more replies from more knowledgeable people.

            Please post updates when you find a solution.


            Regards,
            Ali Pey


            On Wed, Feb 19, 2014 at 5:47 AM, Nick Altmann
            <[email protected] <mailto:[email protected]>>
            wrote:

                Hi!

                How to correctly configure STUN module if we have
                two interfaces with internal addresses where NATed
                two external IPs? (ports are the same)
                I mean something like advertised_address option.

                --
                Nick

                _______________________________________________
                Users mailing list
                [email protected]
                <mailto:[email protected]>
                http://lists.opensips.org/cgi-bin/mailman/listinfo/users



            _______________________________________________
            Users mailing list
            [email protected] <mailto:[email protected]>
            http://lists.opensips.org/cgi-bin/mailman/listinfo/users




        _______________________________________________
        Users mailing list
        [email protected]  <mailto:[email protected]>
        http://lists.opensips.org/cgi-bin/mailman/listinfo/users






_______________________________________________
Users mailing list
[email protected]
http://lists.opensips.org/cgi-bin/mailman/listinfo/users

diff --git a/modules/stun/stun.c b/modules/stun/stun.c
index 88075a7..10494f2 100644
--- a/modules/stun/stun.c
+++ b/modules/stun/stun.c
@@ -30,6 +30,7 @@
 #include "../../socket_info.h"  /* grep_sock_info() */
 #include "../../ip_addr.h"      /* struct socket_info */
 #include "../../str.h"          /* str */
+#include "../../trim.h"
 
 #include "stun.h"
 
@@ -56,15 +57,25 @@ int sockfd4=-1;	/* ip2 port2 */
 int ip1, ip2;
 int port1, port2;
 
+/* advertised IPs and ports, in case we're behind NAT */
+int adv_ip1 = -1, adv_ip2 = -1;
+int adv_port1, adv_port2;
+
+/* Fixup functions */
+int parse_primary_ip(modparam_t type, void *val);
+int parse_primary_port(modparam_t type, void *val);
+int parse_alternate_ip(modparam_t type, void *val);
+int parse_alternate_port(modparam_t type, void *val);
+
 /*
  * Exported parameters ip, port
  */
 static param_export_t params[] = {
-	{"primary_ip",      STR_PARAM,  (void*) &primary_ip},
-	{"primary_port",    STR_PARAM,  (void*) &primary_port},
-	{"alternate_ip",    STR_PARAM,  (void*) &alternate_ip},
-	{"alternate_port",  STR_PARAM,  (void*) &alternate_port},
-	{0, 0, 0}
+	{"primary_ip",      STR_PARAM | USE_FUNC_PARAM,  parse_primary_ip     },
+	{"primary_port",    STR_PARAM | USE_FUNC_PARAM,  parse_primary_port   },
+	{"alternate_ip",    STR_PARAM | USE_FUNC_PARAM,  parse_alternate_ip   },
+	{"alternate_port",  STR_PARAM | USE_FUNC_PARAM,  parse_alternate_port },
+	{ 0, 0, 0}
 };
 
 /* Extra proces for listening loop */
@@ -89,8 +100,6 @@ struct module_exports exports = {
 	child_init          /* per-child init function */
 };
 
-
-
 /* init */
 int bind_ip_port(int ip, int port, int* sockfd){
 
@@ -124,38 +133,21 @@ static int stun_mod_init(void)
 {
 	str s;
 
-	if (primary_ip==NULL || primary_ip[0]==0) {
+	if (!primary_ip || primary_ip[0] == '\0') {
 		LM_ERR("Primary IP was not configured!\n");
 		return -1;
 	}
-	if (inet_pton(AF_INET, primary_ip, &ip1) < 1) {
-		LM_ERR("Invalid ip1 %s : %s\n",primary_ip, strerror(errno));
-		return -1;
-	}
 
-	if (alternate_ip==NULL || alternate_ip[0]==0) {
+	if (!alternate_ip || alternate_ip[0] == '\0') {
 		LM_ERR("Primary IP was not configured!\n");
 		return -1;
 	}
-	if (inet_pton(AF_INET, alternate_ip, &ip2) < 1) {
-		LM_ERR("Invalid ip2 %s : %s\n",alternate_ip, strerror(errno));
-		return -1;
-	}
-
-	ip1 = ntohl(ip1);
-	ip2 = ntohl(ip2);
 
-	port1 = atoi(primary_port);
-	if(!(0<port1 && port1< 65536)){
-		LM_ERR("Invalid port1 %s\n",primary_port);
-		return -1;
-	}
+	if (adv_ip1 != -1 && adv_port1 == 0)
+		adv_port1 = port1;
 
-	port2 = atoi(alternate_port);
-	if(!(0<port2 && port2< 65536)){
-		LM_ERR("Invalid port2 %s\n",alternate_port);
-		return -1;
-	}
+	if (adv_ip2 != -1 && adv_port2 == 0)
+		adv_port1 = port2;
 
 	s.s = primary_ip; s.len = strlen(primary_ip);
 	grep1 = grep_sock_info(&s, (unsigned short)port1, PROTO_UDP);
@@ -251,6 +243,7 @@ void stun_loop(int rank)
 	memset( &ri, 0, sizeof(ri) );
 
 	for(;;){
+		LM_DBG("READING\n");
 		read_set = all_set;
 
 		nready = select(maxfd+1, &read_set, NULL, NULL, NULL);
@@ -729,17 +722,17 @@ int addTlvAttribute(IN_OUT StunMsg* msg , IN StunMsg* srs_msg,
 	    msg->sourceAddress->family = 0x01;
 
 	    if(ctl->sock_outbound == sockfd1){
-		msg->sourceAddress->ip4 = ip1;
-		msg->sourceAddress->port = port1;
+		msg->sourceAddress->ip4 = ADV_IP(ip1, adv_ip1);
+		msg->sourceAddress->port = ADV_PORT(port1, adv_port1);
 	    }else if(ctl->sock_outbound == sockfd2){
-		msg->sourceAddress->ip4 = ip1;
-		msg->sourceAddress->port = port2;
+		msg->sourceAddress->ip4 = ADV_IP(ip1, adv_ip1);
+		msg->sourceAddress->port = ADV_PORT(port2, adv_port2);
 	    }else if(ctl->sock_outbound == sockfd3){
-		msg->sourceAddress->ip4 = ip2;
-		msg->sourceAddress->port = port1;
+		msg->sourceAddress->ip4 = ADV_IP(ip2, adv_ip2);
+		msg->sourceAddress->port = ADV_PORT(port1, adv_port1);
 	    }else if(ctl->sock_outbound == sockfd4){
-		msg->sourceAddress->ip4 = ip2;
-		msg->sourceAddress->port = port2;
+		msg->sourceAddress->ip4 = ADV_IP(ip2, adv_ip2);
+		msg->sourceAddress->port = ADV_PORT(port2, adv_port2);
 	    }
 	    return 2 + 2 + 8;
 
@@ -765,17 +758,17 @@ int addTlvAttribute(IN_OUT StunMsg* msg , IN StunMsg* srs_msg,
 		1 >< 4  ;  2 >< 3
 	     */
 	    if(ctl->sock_inbound == sockfd1){
-		msg->changedAddress->ip4 = ip2;
-		msg->changedAddress->port = port2;
+		msg->changedAddress->ip4 = ADV_IP(ip2, adv_ip2);
+		msg->changedAddress->port = ADV_PORT(port2, adv_port2);
 	    }else if(ctl->sock_inbound == sockfd2){
-		msg->changedAddress->ip4 = ip2;
-		msg->changedAddress->port = port1;
+		msg->changedAddress->ip4 = ADV_IP(ip2, adv_ip2);
+		msg->changedAddress->port = ADV_PORT(port1, adv_port1);
 	    }else if(ctl->sock_inbound == sockfd3){
-		msg->changedAddress->ip4 = ip1;
-		msg->changedAddress->port = port2;
+		msg->changedAddress->ip4 = ADV_IP(ip1, adv_ip1);
+		msg->changedAddress->port = ADV_PORT(port2, adv_port2);
 	    }else if(ctl->sock_inbound == sockfd4){
-		msg->changedAddress->ip4 = ip1;
-		msg->changedAddress->port = port1;
+		msg->changedAddress->ip4 = ADV_IP(ip1, adv_ip1);
+		msg->changedAddress->port = ADV_PORT(port1, adv_port1);
 	    }
 	    return 2 + 2 + 8;
 
@@ -1416,3 +1409,132 @@ void print_hex(IN char* buffer, IN int size){
     }
     LM_DBG("\n");
 }
+
+/**
+ * @buf:        a "ip[ / advertised_ip]" type of string
+ * @rcv_ip:     IP of a receiving interface (dot representation)
+ * @rcv_ip_int: same as above (integer representation)
+ * @adv_ip:     IP of an advertised interface (integer representation)
+ */
+static int parse_ip_modparam(char *buf, char **rcv_ip, int *rcv_ip_int,
+                             int *adv_ip)
+{
+	char *p;
+	str ip;
+
+	p = strchr(buf, '/');
+
+	if (p) {
+		ip.s   = buf;
+		ip.len = p - ip.s;
+	} else {
+		ip.s   = buf;
+		ip.len = strlen(buf);
+	}
+
+	trim(&ip);
+
+	if (p)
+		ip.s[ip.len] = '\0';
+
+	*rcv_ip = ip.s;
+
+	if (inet_pton(AF_INET, ip.s, rcv_ip_int) < 1) {
+		LM_ERR("Invalid ip %s : %s\n", ip.s, strerror(errno));
+		return -1;
+	}
+
+	*rcv_ip_int = ntohl(*rcv_ip_int);
+
+	LM_DBG("Parsed IP: %s %d\n", *rcv_ip, *rcv_ip_int);
+
+	if (!p || !adv_ip)
+		return 0;
+
+	ip.s   = p + 1;
+	ip.len = strlen(ip.s);
+	trim(&ip);
+
+	if (inet_pton(AF_INET, ip.s, adv_ip) < 1) {
+		LM_ERR("Invalid advertised ip %s : %s\n", ip.s, strerror(errno));
+		return -1;
+	}
+
+	*adv_ip = ntohl(*adv_ip);
+
+	LM_DBG("Parsed advertised IP: %.*s %d\n", ip.len, ip.s, *adv_ip);
+
+	return 0;
+}
+
+/**
+ * @buf:        a "port[ / advertised_port]" type of string
+ * @port:       STUN listening port
+ * @adv_port:   STUN advertised port
+ */
+static int parse_port_modparam(char *buf, int *port, int *adv_port)
+{
+	char *p;
+	str st;
+
+	p = strchr(buf, '/');
+
+	if (p) {
+		st.s   = buf;
+		st.len = p - buf;
+	} else {
+		st.s = buf;
+		st.len = strlen(buf);
+	}
+
+	trim(&st);
+
+	if (p)
+		st.s[st.len] = '\0';
+
+	*port = atoi(st.s);
+	if (!(0 < *port && *port < 65536)) {
+		LM_ERR("Invalid port %.*s\n", st.len, st.s);
+		return -1;
+	}
+
+	LM_DBG("Parsed port: %d\n", *port);
+
+	if (!p || !adv_port)
+		return 0;
+
+	st.s   = p + 1;
+	st.len = strlen(st.s);
+	trim(&st);
+
+	*adv_port = atoi(st.s);
+	if (!(0 < *adv_port && *adv_port < 65536)) {
+		LM_ERR("Invalid port %.*s\n", st.len, st.s);
+		return -1;
+	}
+
+	LM_DBG("Parsed advertised port: %d\n", *adv_port);
+
+	return 0;
+}
+
+int parse_primary_ip(modparam_t type, void *val)
+{
+	return parse_ip_modparam(val, &primary_ip, &ip1, &adv_ip1);
+}
+
+int parse_primary_port(modparam_t type, void *val)
+{
+	return parse_port_modparam(val, &port1, &adv_port1);
+}
+
+int parse_alternate_ip(modparam_t type, void *val)
+{
+	return parse_ip_modparam(val, &alternate_ip, &ip2, &adv_ip2);
+}
+
+int parse_alternate_port(modparam_t type, void *val)
+{
+	return parse_port_modparam(val, &port2, &adv_port2);
+}
+
diff --git a/modules/stun/stun.h b/modules/stun/stun.h
index f7336b0..1237ae6 100644
--- a/modules/stun/stun.h
+++ b/modules/stun/stun.h
@@ -47,6 +47,9 @@
 #define IN_OUT
 #define MAX_UNKNOWN_ATTRIBUTES 12
 
+#define ADV_IP(ip, adv_ip) (adv_ip != -1 ? adv_ip : ip)
+#define ADV_PORT(port, adv_port) (adv_port ? adv_port : port)
+
 /* types */
 typedef char        Bool;
 typedef char        T8;
_______________________________________________
Users mailing list
[email protected]
http://lists.opensips.org/cgi-bin/mailman/listinfo/users

Reply via email to