[Serdev] Video NAT traversal

Rodrigo Frez rodrigo at frez.cl
Fri Jan 23 14:05:40 UTC 2004


That I dont know!

-----Original Message-----
From: Adrian Georgescu [mailto:ag at ag-projects.com] 
Sent: Viernes, 23 de Enero de 2004 10:57
To: Rodrigo Frez
Cc: serdev at lists.iptel.org
Subject: Re: [Serdev] Video NAT traversal


Sounds good!

Is this officially accepted by Maxim? Will this be committed to CVS 
main tree?


On 23 Jan 2004, at 14:52, Rodrigo Frez wrote:

> The patch from gbernard works very well with two messenger clients 
> behind nat
>
> #################################################################
>
> --- nathelper.c.org     Sun Jan 18 22:36:30 2004
> +++ nathelper.c Mon Jan 19 14:23:32 2004
> @@ -49,6 +49,10 @@
>   *               proxied and ignores sessions with such flag.
>   *             o Added run-time check for version of command protocol
>   *               supported by the RTP proxy.
> + * 2004-01-19   o Added support for a second RTP flow (ie VIDEO)
> + *              o Added support for RTCP (not tested)
> + *                (G. Bernard IPDirections)
> + *
>   */
>
>  #include "nhelpr_funcs.h"
> @@ -106,7 +110,7 @@
>  static int fix_nated_contact_f(struct sip_msg *, char *, char *);  
> static int fix_nated_sdp_f(struct sip_msg *, char *, char *);  static 
> int extract_mediaip(str *, str *); -static int extract_mediaport(str 
> *, str *);
> +static int extract_mediaport(str *, str *, str *, char *);
>  static int alter_mediaip(struct sip_msg *, str *, str *, str *, int);

> static int alter_mediaport(struct sip_msg *, str *, str *, str *, 
> int);  static char *send_rtpp_command(const struct iovec *, int, int);
> @@ -574,35 +578,59 @@
>  }
>
>  static int
> -extract_mediaport(str *body, str *mediaport)
> +extract_mediaport(str *body, str *mediaport, str *mediactl, char
> *type)
>  {
>         char *cp, *cp1;
>         int len;
>
> -       cp1 = NULL;
> -       for (cp = body->s; (len = body->s + body->len - cp) > 0;) {
> -               cp1 = ser_memmem(cp, "m=", len, 2);
> -               if (cp1 == NULL || cp1[-1] == '\n' || cp1[-1] == '\r')
> -                       break;
> -               cp = cp1 + 2;
> -       }
> +       cp1 = body->s;
>         if (cp1 == NULL) {
> -               LOG(L_ERR, "ERROR: extract_mediaport: no `m=' in
> SDP\n");
> +               LOG(L_ERR, "ERROR: extract_mediaport: no body\n");
>                 return -1;
>         }
> -       mediaport->s = cp1 + 2;
> -       mediaport->len = eat_line(mediaport->s, body->s + body->len -
> -         mediaport->s) - mediaport->s;
> -       trim_len(mediaport->len, mediaport->s, *mediaport);
> -
> -       if (mediaport->len < 7 || memcmp(mediaport->s, "audio", 5) !=
0
> ||
> -         !isspace((int)mediaport->s[5])) {
> -               LOG(L_ERR, "ERROR: extract_mediaport: can't parse `m='
> in SDP\n");
> -               return -1;
> +       while (cp1) {
> +               for (cp = cp1; (len = body->s + body->len - cp) > 0;)
{
> +                       cp1 = ser_memmem(cp, "m=", len, 2);
> +                       if (cp1 == NULL || cp1[-1] == '\n' || cp1[-1]
> ==
> '\r')
> +                               break;
> +                       cp = cp1 + 2;
> +               }
> +               if (cp1 == NULL) {
> +                       LOG(L_ERR,
> +                               "ERROR: extract_mediaport: no `m=%s' 
> + in
> SDP\n",
> +                               type);
> +                       return -1;
> +               }
> +               cp1 += 2;
> +               mediaport->s = cp1;
> +               mediaport->len = eat_line(mediaport->s, body->s +
> body->len -
> +               mediaport->s) - mediaport->s;
> +               trim_len(mediaport->len, mediaport->s, *mediaport);
> +
> +               if (!(mediaport->len < 7 || memcmp(mediaport->s, type,
> 5) != 0
> +                       || !isspace((int)mediaport->s[5]))) break;
>         }
>         cp = eat_space_end(mediaport->s + 5, mediaport->s +
> mediaport->len);
>         mediaport->len = eat_token_end(cp, mediaport->s +
> mediaport->len) - cp;
>         mediaport->s = cp;
> +       mediactl->len = -1;
> +       if (cp1 == NULL) {
> +               LOG(L_ERR, "ERROR: extract_mediaport: no rctp port
> found\n");
> +               return 1;
> +       }
> +       for (cp = cp1; (len = body->s + body->len - cp) > 0;) {
> +               cp1 = ser_memmem(cp, "a=rtcp:", len, 7);
> +               if (cp1 == NULL || cp1[-1] == '\n' || cp1[-1] == '\r')
> +                       break;
> +               cp = cp1 + 7;
> +       }
> +       if (cp1 != NULL) {
> +               cp1 += 7;
> +               mediactl->s = cp1;
> +               mediactl->len = eat_line(mediactl->s, body->s +
> body->len -
> +                       mediactl->s) - mediactl->s;
> +               trim_len(mediactl->len, mediactl->s, *mediactl);
> +       }
>         return 1;
>  }
>
> @@ -774,7 +802,7 @@
>  static int
>  unforce_rtp_proxy_f(struct sip_msg* msg, char* str1, char* str2)  {
> -       str callid, from_tag, to_tag;
> +       str callid, from_tag, to_tag, tag;
>         struct iovec v[4 + 3] = {{"D", 1}, {" ", 1}, {NULL, 0}, {" ", 
> 1}, {NULL, 0}, {" ", 1}, {NULL, 0}};
>                                  /* 0 */   /* 1 */   /* 2 */    /* 3
*/
> /* 4 */    /* 5 */   /* 6 */
>
> @@ -795,10 +823,26 @@
>                 LOG(L_ERR, "ERROR: unforce_rtp_proxy: can't get From 
> tag\n");
>                 return -1;
>         }
> -       STR2IOVEC(callid, v[2]);
> +       tag.s = pkg_malloc(callid.len + 6);
> +       if (tag.s == NULL) {
> +               LOG(L_ERR, "ERROR: type_tag: out of memory\n");
> +               return -1;
> +       }
> +       strcpy(tag.s, "audio-");
> +       strncat(tag.s, callid.s, callid.len);
> +       tag.len = callid.len + 6;
> +       tag.s[tag.len] = (char)0;
> +       STR2IOVEC(tag, v[2]);
>         STR2IOVEC(from_tag, v[4]);
>         STR2IOVEC(to_tag, v[6]);
>         send_rtpp_command(v, (to_tag.len > 0) ? 7 : 5, 0);
> +       strcpy(tag.s, "video-");
> +       strncat(tag.s, callid.s, callid.len);
> +       tag.len = callid.len + 6;
> +       tag.s[tag.len] = (char)0;
> +       STR2IOVEC(tag, v[2]);
> +       send_rtpp_command(v, (to_tag.len > 0) ? 7 : 5, 0);
> +       pkg_free(tag.s);
>
>         return 1;
>  }
> @@ -806,10 +850,12 @@
>  static int
>  force_rtp_proxy_f(struct sip_msg* msg, char* str1, char* str2)  {
> -       str body, body1, oldport, oldip, oldip1, newport, newip;
> -       str callid, from_tag, to_tag;
> -       int create, port, len;
> +       str body, body1, oldport, oldctl, oldvport, oldvctl, oldip,
> oldip1;
> +        str newvport, newport, newip;
> +       str callid, from_tag, to_tag, tag;
> +       int create, port, portv=0, len;
>         char buf[16];
> +       char fub[16];
>         char *cp, *cp1;
>         struct lump* anchor;
>         struct iovec v[6 + 5] = {{"U", 1}, {" ", 1}, {NULL, 0}, {" ", 
> 1}, {NULL, 7}, {" ", 1}, {NULL, 1}, {" ", 1}, {NULL, 0}, {" ", 1}, 
> {NULL, 0}}; @@ -868,29 +914,80 @@
>         if (extract_mediaip(&body1, &oldip1) == -1) {
>                 oldip1.len = 0;
>         }
> -       if (extract_mediaport(&body, &oldport) == -1) {
> -               LOG(L_ERR, "ERROR: force_rtp_proxy: can't extract
media
> port "
> +       if (extract_mediaport(&body, &oldport, &oldctl, "audio") == 
> + -1)
> {
> +               LOG(L_ERR, "ERROR: force_rtp_proxy: can't extract 
> + audio
> port "
>                     "from the message\n");
>                 return -1;
>         }
> +       if (oldctl.len > 0)
> +               LOG(L_DBG, "DEBUG: Found Audio RTP/RTCP ports\n");
> +       else
> +               LOG(L_DBG, "DEBUG: Found Audio RTP port\n");
> +       if (extract_mediaport(&body, &oldvport, &oldvctl, "video") ==
> -1) {
> +               LOG(L_ERR, "ERROR: force_rtp_proxy: can't extract 
> + video
> port "
> +                   "from the message\n");
> +               oldvport.len = oldvctl.len = -1;
> +       }
> +       if (oldvctl.len > 0)
> +               LOG(L_DBG, "DEBUG: Found Video RTP/RTCP ports\n");
> +       else if (oldvport.len > 0)
> +               LOG(L_DBG, "DEBUG: Found Video RTP port\n");
>         newip.s = ip_addr2a(&msg->rcv.src_ip);
>         newip.len = strlen(newip.s);
>         if (create == 0)
>                 v[0].iov_base = "L";
> -       STR2IOVEC(callid, v[2]);
> +       tag.s = pkg_malloc(callid.len + 6);
> +       if (tag.s == NULL) {
> +               LOG(L_ERR, "ERROR: force_rtpproxy: out of memory\n");
> +               return -1;
> +       }
> +       strcpy(tag.s, "audio-");
> +       strncat(tag.s, callid.s, callid.len);
> +       tag.len = callid.len + 6;
> +       tag.s[tag.len] = (char)0;
> +       STR2IOVEC(tag, v[2]);
>         STR2IOVEC(newip, v[4]);
>         STR2IOVEC(oldport, v[6]);
>         STR2IOVEC(from_tag, v[8]);
>         STR2IOVEC(to_tag, v[10]);
> +       LOG(L_DBG, "DEBUG: Call-ID set to: %s\n", tag.s);
>         cp = send_rtpp_command(v, (to_tag.len > 0) ? 11 : 9, 1);
> +       pkg_free(tag.s);
>         if (cp == NULL)
>                 return -1;
> +       LOG(L_DBG, "DEBUG: New audio port is %s", cp);
>         port = atoi(cp);
> -       if (port <= 0 || port > 65535)
> +       if (port <= 0 || port > 65534)
>                 return -1;
>
>         newport.s = buf;
>         newport.len = sprintf(buf, "%d", port);
> +
> +       if (oldvport.len > 0) {
> +               tag.s = pkg_malloc(callid.len + 6);
> +               if (tag.s == NULL) {
> +                       LOG(L_ERR, "ERROR: force_rtpproxy: out of
> memory\n");
> +                       return -1;
> +               }
> +               strcpy(tag.s, "video-");
> +               strncat(tag.s, callid.s, callid.len);
> +               tag.len = callid.len + 6;
> +               tag.s[tag.len] = (char)0;
> +               STR2IOVEC(tag, v[2]);
> +               STR2IOVEC(oldvport, v[6]);
> +               LOG(L_DBG, "DEBUG: Call-ID set to: %s\n", tag.s);
> +               cp = send_rtpp_command(v, (to_tag.len > 0) ? 11 : 9,
> 1);
> +               pkg_free(tag.s);
> +               if (cp == NULL)
> +                       return -1;
> +               LOG(L_DBG, "DEBUG: New video port is %s", cp);
> +               portv = atoi(cp);
> +               if (portv <= 0 || portv > 65534)
> +                       return -1;
> +               newvport.s = fub;
> +               newvport.len = sprintf(fub, "%d", portv);
> +       }
> +
>         newip.s = ip_addr2a(&msg->rcv.dst_ip);
>         newip.len = strlen(newip.s);
>
> @@ -901,6 +998,21 @@
>                 return -1;
>         if (alter_mediaport(msg, &body, &oldport, &newport, 0) == -1)
>                 return -1;
> +       port++;
> +       newport.s = buf;
> +       newport.len = sprintf(buf, "%d", port);
> +       if (oldctl.len > 0 &&
> +               alter_mediaport(msg, &body, &oldctl, &newport, 0) ==
> -1)
> +                       return -1;
> +       if (oldvport.len > 0 &&
> +               alter_mediaport(msg, &body, &oldvport, &newvport, 0) 
> + ==
> -1)
> +                       return -1;
> +       portv++;
> +       newvport.s = fub;
> +       newvport.len = sprintf(fub, "%d", portv);
> +       if (oldvport.len > 0 && oldvctl.len > 0 &&
> +               alter_mediaport(msg, &body, &oldvctl, &newvport, 0) ==
> -1)
> +                       return -1;
>
>         cp = pkg_malloc(ANORTPPROXY_LEN * sizeof(char));
>         if (cp == NULL) {
>
> #################################################################
> -----Original Message-----
> From: Adrian Georgescu [mailto:ag at ag-projects.com]
> Sent: Viernes, 23 de Enero de 2004 10:43
> To: serdev at lists.iptel.org
> Subject: [Serdev] Video NAT traversal
>
>
> If nobody is bussy with this I am prepared to allocated resources for 
> this project.
>
> I will check personally with Maxim but any feed back is appreciated.
>
> ---
> Adrian
>
> _______________________________________________
> Serdev mailing list
> serdev at lists.iptel.org http://lists.iptel.org/mailman/listinfo/serdev
>
>






More information about the Serdev mailing list