[Asterisk-Dev] NAT patch for chan_sip.c
Mark Spencer
markster at digium.com
Thu Oct 30 13:11:41 MST 2003
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
> >>
> >>
> >
> >
> > _______________________________________________
> > Asterisk-Dev mailing list
> > Asterisk-Dev at lists.digium.com
> > http://lists.digium.com/mailman/listinfo/asterisk-dev
> >
>
>
> --
> *** Olle E. Johansson, oej at edvina.net
>
> Mobile +46 70 593 68 51, Edvina AB, http://www.edvina.net
> Runbovägen 10, 192 48 Sollentuna, Sweden
> Phone: +46 8 594 78 810, Fax: +46 8 594 78 820
>
>
> _______________________________________________
> 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