>> > Right now, my NAPT SIP code (http://www.siphappens.com/masquerade/)
>> >doesn't re-modify the topmost Via on responses. This is because I
>> >figured that end devices wouldn't bother checking if the message is
>> >actually for them if they got a response.
>>
>> Actually, I just checked, and our client does (part of the "sanity
>> checking" routing) -- so it's not necessarily a good assumption.
>
> Brutal. Can you think of any time where this sanity check would pay
>off? I mean, in my opinion, you should fail only when the call leg
>match fails...
I suppose I should clarify. We have our SIP stack as an isolated
library, which the client is built upon. The stack itself performs
this sanity check. It's a fast way to verify "is this message
actually intended for me, or has some bozo server just started
flinging messages in random directions?"
> The real reason I'm not adding my own Via header (and also not
>demasquerading the via header) is because if I don't, I can get away
>without modifying incoming SIP messages from the Internet. Otherwise, I
>have to find out if the request is a response, and if it is, strip out
>the Via.
After thinking about it further, I'm becoming more convinced that
you *should* be inserting your own Via header. If you just leave the
IP address alone, but tweak the port, you'll need to tweak the
port *back* on the response, or risk rejection by the next downstream
host.
While stripping the via will incur a very slight performance hit, you
can minimize this by using vector writes (which should avoid
unnecessary copying). I'd actually recommend against the use of
regexes (use a tiny FSM instead), but it makes my example more
consise and easy to understand. Add bounds checking as necessary.
This is a fairly cheap way to do it; you end up scanning each
character once, up to the end of the first Via header. Everything
else is constant time.
int bytesWritten;
char *topViaStart, *topViaEnd;
const struct iovec *respVector[2];
if (!strncmp(buffer,"SIP/2.0",7)) /* It's a response */
{
topViaStart = grep(buffer + 7,"[\r\n][Vv]([Ii][Aa])?[ \t]*:");
topViaStart++; /* skip \r or \n */
topViaEnd = topViaStart;
while (topViaEnd != '\r' && topViaEnd != '\n') topViaEnd++;
while (topViaEnd == '\r' || topViaEnd == '\n') topViaEnd++;
respVector[0].iov_base = buffer;
respVector[0].iov_len = topViaStartbuffer - buffer;
respVector[1].iov_base = topViaEnd;
respVector[1].iov_len = bufferEnd - topViaEnd;
bytesWritten = writev(socket, respVector, 2);
}
else
{
bytesWritten = write(socket, buffer, bufferEnd-buffer);
}
--
Adam Roach, Ericsson Inc. | Ph: +1 972 583 7594 | 1010 E. Arapaho, MS L-04
[EMAIL PROTECTED] | Fax: +1 972 669 0154 | Richardson, TX 75081 USA