[Asterisk-Dev] NAT patch for chan_sip.c

John Todd jtodd at loligo.com
Thu Oct 30 14:58:10 MST 2003


Your $125-an-hour time towards the Asterisk project's goals could be 
well spent with searching Google and posting these very items, 
instead of asking Mark to do it.

JT


>Mark,
>
>1) A pointer to some STUN docs and/or code would help.
>
>2) I thought STUN only works on "STUN aware" firewalls.
>Ansering #1 above may anser this.
>
>There are now two independent patches that stuff
>public address in outbound SIP.  Perhaps we do this
>_and_ STUN.  Knowing #1 will help.
>
>
>
>
>--- Mark Spencer <markster at digium.com> wrote:
>>  I still believe the right answer is STUN.  Is anyone going to
>>  implement
>>  it?
>>
>>  Mark
>>
>>  On Thu, 30 Oct 2003, Olle E. Johansson wrote:
>>
>>  > Jeremy McNamara wrote:
>>  >
>>  > > What does this patch do that nat=yes doesn't accomplish?
>>  > It may help Asterisk as a SIP client, not a SIP server, to connect
>>  to
>>  > outside SIP servers like fwd.pulver.com. However, it needs to be
>>  > tested for this situation.
>>  >
>>  > nat=yes works when * is a SIP server. There seems to be a problem
>>  when
>>  > you have clients both inside a NAT and outside, propably with the
>>  RTP
>>  > stream after re-invite. Maybe this patch with some additional magic
>>  > can make asterisk NOT re-invite when setting up a call in this
>>  > situation, but stay in the media stream.
>>  >
>>  > /Olle
>>  > >
>>  > > Also, this should be submitted to http://bugs.digium.com/ not the
>>  > > mailing list.
>>  > >
>>  > >
>>  > >
>>  > > Jeremy McNamara
>>  > >
>>  > >
>>  > >
>>  > > William Waites wrote:
>>  > >
>>  > >> This is not thoroughly tested, but seems to work for me. It
>>  consists in
>>  > >> three changes:
>>  > >>
>>  > >> 1. introduction of inside_net, inside_mask and outside_addr
>>  global
>>  > >>    parameters for sip.conf
>>  > >> 2. change transmit_register to call ast_sip_ouraddrfor() before
>>  > >>    building the contact header
>>  > >> 3. change ast_sip_ouraddrfor() to check if the destination is
>>  > >>    internal or external. if internal, continue as usual, if
>>  external
>>  > >>    return outside_addr in *us
>>  > >>
>>  > >> Consider this patch suitably disclaimed, and without any
>>  warranty
>>  > >> whatsoever. This code was produced on behalf of NTG Clarity
>>  Networks,
>>  > >> MontrÈal.
>>  > >>
>>  > >> Index: chan_sip.c
>>  > >>
>>  ===================================================================
>>  > >> RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v
>>  > >> retrieving revision 1.203
>>  > >> diff -u -r1.203 chan_sip.c
>>  > >> --- chan_sip.c  25 Oct 2003 17:41:02 -0000      1.203
>>  > >> +++ chan_sip.c  30 Oct 2003 17:23:54 -0000
>>  > >> @@ -390,6 +390,9 @@
>>  > >>
>>  > >>
>>  > >> static struct sockaddr_in bindaddr;
>>  > >> +static struct sockaddr_in inside_net;
>>  > >> +static struct sockaddr_in inside_mask;
>>  > >> +static struct sockaddr_in outside_addr;
>>  > >>
>>  > >> static struct ast_frame  *sip_read(struct ast_channel *ast);
>>  > >> static int transmit_response(struct sip_pvt *p, char *msg,
>>  struct
>>  > >> sip_request
>>  > >> *req);
>  > > >> @@ -425,7 +428,15 @@
>  > > >>
>  > > >> static int ast_sip_ouraddrfor(struct in_addr *them, struct
>  > in_addr *us)
>  > > >> {
>  > > >> -       if (bindaddr.sin_addr.s_addr)
>  > > >> +       /*
>  > > >> +         check to see if them is contained in our
>>  inside_net/mask,
>>  > >> +         if not, use our outside_addr for us, otherwise use the
>>  > >> +         real internal address in bindaddr
>>  > >> +         */
>>  > >> +       if (inside_net.sin_addr.s_addr &&
>>  outside_addr.sin_addr.s_addr &&
>>  > >> +           ((htonl(them->s_addr) &
>>  htonl(inside_net.sin_addr.s_addr)) !=
>>  > >> htonl(inside_net.sin_addr.s_addr)))
>>  > >> +               memcpy(us, &outside_addr.sin_addr, sizeof(struct
>>  > >> in_addr));
>>  > >> +       else if (bindaddr.sin_addr.s_addr)
>>  > >>                memcpy(us, &bindaddr.sin_addr, sizeof(struct
>>  in_addr));
>>  > >>        else
>>  > >>                return ast_ouraddrfor(them, us);
>>  > >> @@ -2951,6 +2962,8 @@
>>  > >>        char via[80];
>>  > >>        char addr[80];
>>  > >>        struct sip_pvt *p;
>>  > >> +       struct hostent *hp;
>  > > >> +
>>  > >>        /* exit if we are already in process with this registrar
>>  ?*/
>>  > >>        if ( r == NULL || ((auth==NULL) &&
>>  > >> (r->regstate==REG_STATE_REGSENT ||
>>  > >> r->regstate==REG_STATE_AUTHSENT))) {
>>  > >>                ast_log(LOG_NOTICE, "Strange, trying to register
>>  when
>>  > >> registration already pending\n");
>>  > >> @@ -2984,9 +2997,16 @@
>>  > >>                        strncpy(p->peername, r->username,
>>  > >> sizeof(p->peername)-1);
>>  > >>                strncpy(p->username, r->username,
>>  sizeof(p->username)-1);
>>  > >>                strncpy(p->exten, r->contact, sizeof(p->exten) -
>>  1);
>>  > >> -               /* Always bind to our IP if specified */
>>  > >> -               if (bindaddr.sin_addr.s_addr)
>>  > >> -                       memcpy(&p->ourip, &bindaddr.sin_addr,
>>  > >> sizeof(p->ourip));
>>  > >> +
>>  > >> +               /*
>>  > >> +                 check which address we should use in our
>>  contact
>>  > >> header +                 based on whether the remote host is on
>>  the
>>  > >> external or
>>  > >> +                 internal network so we can register through
>>  nat
>>  > >> +                */
>>  > >> +               if ((hp = gethostbyname(r->hostname))) {
>>  > >> +                       if (ast_sip_ouraddrfor((struct in_addr
>>  > >> *)hp->h_addr,
>>  > >> &p->ourip))
>>  > >> +                               memcpy(&p->ourip,
>>  &bindaddr.sin_addr,
>>  > >> sizeof(p->ourip));
>>  > >> +               }
>>  > >>                build_contact(p);
>>  > >>        }
>>  > >>
>>  > >> @@ -5921,6 +5941,10 @@
>>  > >>        sip_prefs_free();
>>  > >>
>>  > >>        memset(&bindaddr, 0, sizeof(bindaddr));
>>  > >> +       memset(&inside_net, 0, sizeof(inside_net));
>>  > >> +       memset(&inside_mask, 0, sizeof(inside_mask));
>>  > >> +       memset(&outside_addr, 0, sizeof(outside_addr));
>>  > >> +
>>  > >>        /* Initialize some reasonable defaults */
>>  > >>        strncpy(context, "default", sizeof(context) - 1);
>>  > >>        strcpy(language, "");
>>  > >> @@ -5979,6 +6003,21 @@
>>  > >>                        } else {
>>  > >>                                memcpy(&bindaddr.sin_addr,
>>  hp->h_addr,
>>  > >> sizeof(bindaddr.sin_addr));
>>  > >>                        }
>>  > >> +               } else if (!strcasecmp(v->name, "inside_net")) {
>>  > >> +                       if (!(hp = gethostbyname(v->value)))
>>  > >> +                               ast_log(LOG_WARNING, "Invalid
>>  INSIDE_NET:
>>  > >> %s\n", v->value);
>>  > >> +                       else +
>>  > >> memcpy(&inside_net.sin_addr, hp->h_addr,
>>  > >> sizeof(inside_net.sin_addr));
>>  > >> +               } else if (!strcasecmp(v->name, "inside_mask"))
>>  {
>>  > >> +                       if (!(hp = gethostbyname(v->value)))
>>  > >> +                               ast_log(LOG_WARNING, "Invalid
>>  > >> INSIDE_MASK:
>>  > >> %s\n", v->value);
>>  > >> +                       else
>>  > >> +                               memcpy(&inside_mask.sin_addr,
>>  hp->h_addr,
>>  > >> sizeof(inside_mask.sin_addr));
>>  > >> +               } else if (!strcasecmp(v->name, "outside_addr"))
>>  {
>>  > >> +                       if (!(hp = gethostbyname(v->value)))
>>  > >> +                               ast_log(LOG_WARNING, "Invalid
>>  > >> OUTSIDE_MASK:
>>  > >> %s\n", v->value);
>>  > >> +                       else
>>  > >> +                               memcpy(&outside_addr.sin_addr,
>>  > >> hp->h_addr,
>>  > >> sizeof(outside_addr.sin_addr));
>>  > >>                } else if (!strcasecmp(v->name, "allow")) {
>>  > >>                        format = ast_getformatbyname(v->value);
>>  > >>                        if (format < 1)
>>  > >>
>>  > >> _______________________________________________
>>  > >> Asterisk-Dev mailing list
>>  > >> Asterisk-Dev at lists.digium.com
>>  > >> http://lists.digium.com/mailman/listinfo/asterisk-dev
>>
>=== message truncated ===
>
>
>=====
>Chris Albertson
>   Home:   310-376-1029  chrisalbertson90278 at yahoo.com
>   Cell:   310-990-7550
>   Office: 310-336-5189  Christopher.J.Albertson at aero.org
>   KG6OMK
>
>__________________________________
>Do you Yahoo!?
>Exclusive Video Premiere - Britney Spears
>http://launch.yahoo.com/promos/britneyspears/
>_______________________________________________
>Asterisk-Dev mailing list
>Asterisk-Dev at lists.digium.com
>http://lists.digium.com/mailman/listinfo/asterisk-dev




More information about the asterisk-dev mailing list