Unix Programming - recvfrom strange behaviour

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > November 2004 > recvfrom strange behaviour





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author recvfrom strange behaviour
pink_dot

2004-11-22, 2:47 am

Hi!

I have a problem. The situation is as follows:

A --> N | --> B

The host A is behind NAT machine (N). The host B is on the open
Internet. I'm sending a UDP datagram from host A (using socket bound to
some port) to host B. On B I'm using recvfrom to get the datagram and to
determine sender's IP/port. And to my great surprise I get: (N's
IP)/(A's port) pair, while I am expecting (N's IP)/(N's port)! It seems
that NAT changes IP, but leaves port number untouched which is (imho)
very strange, as it would make impossible for B to send any reply back.

I've observed the same behaviour on three different NAT's (different
networks). It's not (imho) a matter of restrictive NAT configuration as
there are applications installed on A which use UDP, and datagrams are
coming back and forth with no difficulty.

How can I get with recfrom mapped port number, that I could use to send
a reply back?

Thanks in advance for your answer.
Alex Fraser

2004-11-22, 2:47 am

"pink_dot" <test881@gazeta.pl> wrote in message
news:cnsa7n$ibe$1@inews.gazeta.pl...
[snip]
> It seems that NAT changes IP, but leaves port number untouched which is
> (imho) very strange, as it would make impossible for B to send any reply
> back.


Not at all. Most of the time, no port translation is necessary, although the
NAT router will need to remember the port (as well as the original and
translated IP addresses). In effect, the port has been translated to the
same port. You should have no trouble replying.

Alex


pink_dot

2004-11-22, 7:49 am


> Not at all. Most of the time, no port translation is necessary, although the
> NAT router will need to remember the port (as well as the original and
> translated IP addresses). In effect, the port has been translated to the
> same port. You should have no trouble replying.


Thanks for your answer. Unfortunatelly replies are not coming back. I'm
passing sendto() the same SOCKADDR struct, that I used with recvfrom.

(...)
sockaddr_in sa;
memset((void*)&sa, 0, sizeof(sa));
sa_len = sizeof(sa);
len = recvfrom(s, buffer, BUF_SIZE, 0, (sockaddr*)sa, &sa_len);
// everything is ok - len>0, sa.sin_addr & sa.sin_port
// are containing valid values
res = sendto(s, buffer, len, 0, (sockaddr*)sa, sa_len);
// res=len - everything seems fine

Is there something wrong with my code?

Greets,
Alex Fraser

2004-11-22, 7:49 am

"pink_dot" <test881@gazeta.pl> wrote in message
news:cnsgdc$gqt$1@inews.gazeta.pl...
>
> Thanks for your answer. Unfortunatelly replies are not coming back. I'm
> passing sendto() the same SOCKADDR struct, that I used with recvfrom.
>
> (...)
> sockaddr_in sa;
> memset((void*)&sa, 0, sizeof(sa));
> sa_len = sizeof(sa);
> len = recvfrom(s, buffer, BUF_SIZE, 0, (sockaddr*)sa, &sa_len);
> // everything is ok - len>0, sa.sin_addr & sa.sin_port
> // are containing valid values
> res = sendto(s, buffer, len, 0, (sockaddr*)sa, sa_len);
> // res=len - everything seems fine


This looks fine to me. Look in the client code, and/or get tcpdump on the
case. UDP does not give you guaranteed delivery, but it's fairly unlikely
that this is biting you, particularly if the datagrams are small (<512
bytes). The only other possibility that springs to mind is some kind of
routing problem, independent of the NAT.

Alex


Bjørn Augestad

2004-11-22, 7:49 am

pink_dot wrote:

>
>
>
> Thanks for your answer. Unfortunatelly replies are not coming back. I'm
> passing sendto() the same SOCKADDR struct, that I used with recvfrom.
>
> (...)
> sockaddr_in sa;
> memset((void*)&sa, 0, sizeof(sa));
> sa_len = sizeof(sa);
> len = recvfrom(s, buffer, BUF_SIZE, 0, (sockaddr*)sa, &sa_len);
> // everything is ok - len>0, sa.sin_addr & sa.sin_port
> // are containing valid values
> res = sendto(s, buffer, len, 0, (sockaddr*)sa, sa_len);
> // res=len - everything seems fine
>
> Is there something wrong with my code?


Yes, there is. ;-)

Use "(sockaddr*)&sa" instead of "(sockaddr*)sa" in your calls to
recvfrom() and sendto(). Just &sa will suffice, BTW.


Bjørn


>
> Greets,

Alex Fraser

2004-11-22, 7:49 am

"Bjørn Augestad" <boa@metasystems.no> wrote in message
news:rfkod.5181$HA5.621678@juliett.dax.net...
> pink_dot wrote:
>
> Yes, there is. ;-)
>
> Use "(sockaddr*)&sa" instead of "(sockaddr*)sa" in your calls to
> recvfrom() and sendto().


Good catch, but I don't think it will compile without the '&' (how should
the compiler convert a struct type to a pointer type?), so I guess the code
was retyped instead of copied (which is always a mistake).

> Just &sa will suffice, BTW.


Not on any system I've used, at least with C. The prototype for socket
functions that take an address always specify ([const] struct sockaddr *),
and the cast is therefore required to convert from, in this case, (struct
sockaddr_in *). I'n pretty sure it could work as you describe using C++
features, but I've never seen that done.

Alex


Bjørn Augestad

2004-11-22, 7:49 am

Alex Fraser wrote:

> "Bjørn Augestad" <boa@metasystems.no> wrote in message
> news:rfkod.5181$HA5.621678@juliett.dax.net...
>
>
>
> Good catch, but I don't think it will compile without the '&' (how should
> the compiler convert a struct type to a pointer type?), so I guess the code
> was retyped instead of copied (which is always a mistake).
>
>
>
>
> Not on any system I've used, at least with C. The prototype for socket
> functions that take an address always specify ([const] struct sockaddr *),
> and the cast is therefore required to convert from, in this case, (struct
> sockaddr_in *). I'n pretty sure it could work as you describe using C++
> features, but I've never seen that done.
>



You're right. I noticed my mistake 2 seconds after I pressed the Send
button. Somehow I managed to read sockaddr_in as sockaddr. My only
excuse is that I have a cold and should probably have stayed in bed. ;-)

Sorry for the confusion.
Bjørn


> Alex
>
>

Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com