Netdev List
 help / color / mirror / Atom feed
* Re: [tproxy] udp + tproxy
       [not found] ` <20081112185910.GA1793@sch.bme.hu>
@ 2008-11-12 19:27   ` Balazs Scheidler
  2008-11-13  7:17     ` Jan Engelhardt
  0 siblings, 1 reply; 4+ messages in thread
From: Balazs Scheidler @ 2008-11-12 19:27 UTC (permalink / raw)
  To: KOVACS Krisztian; +Cc: Andrey Luzgin, tproxy, netfilter-devel, netdev

On Wed, 2008-11-12 at 19:59 +0100, KOVACS Krisztian wrote:
> Hi,
> 
> On sze, nov 12, 2008 at 11:40:30 +0000, Andrey Luzgin wrote:
> > Hello,
> > 
> > While I can see example of using udp on tproxy2 onto the
> > redirect-udp-recv.c
> > file, I can't find equivalent on tproxy4.
> > 
> > For getting the original destination IP, I just use setsockopt
> > IP_PKTINFO:
> > setsockopt(sd, SOL_IP, IP_PKTINFO , &flags, sizeof(flags));
> > 
> > But I don't know how to get the original destination port:
> > 
> > a) I manually defined IP_RECVORIGADDRS  to be 11273 as I find on
> > tproxy2:
> > setsockopt(sd, SOL_IP, IP_RECVORIGADDRS , &flags, sizeof(flags));
> > but the setsockopt failed.
> > 
> > b) the getsockname give me the server listening port.
> 
> 
> Since tproxy 4 (unlike tproxy 2) doesn't modify the incoming packets in
> any way you should be able to get the correct destination address by
> simply calling recvfrom() and using the source address returned by the
> kernel.
> 

This is not true, recvfrom() returns the client address and does not
return the original destination. There was a hack in 2.2 kernels, that
it could return the targeted address in the 2nd half of the "struct
sockaddr_in" structure.

But that hack was crude. 

I can only see two options to proceed with full udp proxying: accept()
support for UDP, or a recvmsg() ancillary data (IP_RECVORIGADDRS) as
above.

I'll see whether I can come up with a patch for the latter.

In Zorp we're using accept() for UDP sockets, but I doubt it could be
integrated to mainline, the other option is doable, although potentially
racy.

-- 
Bazsi



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [tproxy] udp + tproxy
  2008-11-12 19:27   ` [tproxy] udp + tproxy Balazs Scheidler
@ 2008-11-13  7:17     ` Jan Engelhardt
  2008-11-13  7:25       ` Balazs Scheidler
  0 siblings, 1 reply; 4+ messages in thread
From: Jan Engelhardt @ 2008-11-13  7:17 UTC (permalink / raw)
  To: Balazs Scheidler
  Cc: KOVACS Krisztian, Andrey Luzgin, tproxy, netfilter-devel, netdev


On Wednesday 2008-11-12 20:27, Balazs Scheidler wrote:
>> 
>> Since tproxy 4 (unlike tproxy 2) doesn't modify the incoming packets in
>> any way you should be able to get the correct destination address by
>> simply calling recvfrom() and using the source address returned by the
>> kernel.
>
>This is not true, recvfrom() returns the client address and does not
>return the original destination.

Mh, perhaps getsockname() could do something - well, at least
if used with accept() and as such, mostly for TCP only.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [tproxy] udp + tproxy
  2008-11-13  7:17     ` Jan Engelhardt
@ 2008-11-13  7:25       ` Balazs Scheidler
  2008-11-13  8:44         ` Henrik Nordstrom
  0 siblings, 1 reply; 4+ messages in thread
From: Balazs Scheidler @ 2008-11-13  7:25 UTC (permalink / raw)
  To: Jan Engelhardt
  Cc: KOVACS Krisztian, Andrey Luzgin, tproxy, netfilter-devel, netdev

On Thu, 2008-11-13 at 08:17 +0100, Jan Engelhardt wrote:
> On Wednesday 2008-11-12 20:27, Balazs Scheidler wrote:
> >> 
> >> Since tproxy 4 (unlike tproxy 2) doesn't modify the incoming packets in
> >> any way you should be able to get the correct destination address by
> >> simply calling recvfrom() and using the source address returned by the
> >> kernel.
> >
> >This is not true, recvfrom() returns the client address and does not
> >return the original destination.
> 
> Mh, perhaps getsockname() could do something - well, at least
> if used with accept() and as such, mostly for TCP only.
> 

Well, here's my other mail on the subject on the tproxy list, it
basically details that we do have an implementation of accept() for UDP
which we use in production. But I'm not sure that could be integrated to
mainline.

-<- quote ->-

Well, for supporting UDP with tproxy4 we use a different approach:
udp_accept(), you can find it in the BalaBit kernel patch tree at
http://www.balabit.com/downloads/files/kernel-patches/

The way udp_accept() works is as follows:
  * the userspace proxy opens a "listening" udp socket, binds it to the
listening address, performs no connect() calls
  * tproxy redirects packets to this socket just like in the case for
TCP
  * whenever the socket becomes readable from the userspace proxy,
accept() is invoked on the UDP socket, this accept() is implemented by
the patch mentioned above
  * in kernel space: the first packet is consulted from the socket
buffer of the listening socket
  * the kernel opens a new UDP socket, just like the accept() call for
TCP does
  * this new UDP socket is bound this way: 
    * local address is the same as the destination address of the
incoming packet
    * destination address is the same as the source address of the
incoming packet
  * the socket buffer of the listening socket is traversed, and each
packet having the same IP addresses as the first packet is moved to the
newly opened socket; this traversal is happening in an atomic context,
thus no new packets can arrive
  * a reference to the newly opened socket is returned to userspace
  * when a new packet comes in, the socket lookup will prefer the
completely bound socket over the listening socket

Since at the end of the accept() call you get a completely bound socket,
you can simply call getsockname() to query the target address, just like
with TCP.

Hope this helps.

PS: I was talking to Patrick McHardy whether to send the udp_accept()
patch for kernel inclusion, he said it might be worth trying, however he
was not completely sure it'd be integrated. So I didn't push it so far.


-- 
Bazsi



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [tproxy] udp + tproxy
  2008-11-13  7:25       ` Balazs Scheidler
@ 2008-11-13  8:44         ` Henrik Nordstrom
  0 siblings, 0 replies; 4+ messages in thread
From: Henrik Nordstrom @ 2008-11-13  8:44 UTC (permalink / raw)
  To: Balazs Scheidler
  Cc: Jan Engelhardt, KOVACS Krisztian, Andrey Luzgin, tproxy,
	netfilter-devel, netdev

[-- Attachment #1: Type: text/plain, Size: 784 bytes --]

On tor, 2008-11-13 at 08:25 +0100, Balazs Scheidler wrote:

> PS: I was talking to Patrick McHardy whether to send the udp_accept()
> patch for kernel inclusion, he said it might be worth trying, however he
> was not completely sure it'd be integrated. So I didn't push it so far.

I second this, but also think that it will see some initial resistance.

I guess the main complaint (assuming code is in good shale) will be that
UDP does not have any sender verification, which means it's very easy to
flood the kernel with UDP "connection requests". But on the other hand
there is also no SYN_RECV or FIN_WAIT/TIME_WAIT states which may hold up
things beyond CPU processing speed so this is not by far as big problem
to deal with as in the TCP case..

Regards
Henrik

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 307 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2008-11-13  8:44 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <1226490030.31896.12.camel@sysandrey.icomswg.local>
     [not found] ` <20081112185910.GA1793@sch.bme.hu>
2008-11-12 19:27   ` [tproxy] udp + tproxy Balazs Scheidler
2008-11-13  7:17     ` Jan Engelhardt
2008-11-13  7:25       ` Balazs Scheidler
2008-11-13  8:44         ` Henrik Nordstrom

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox