[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