>> >  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

Reply via email to