users@grizzly.java.net

Re: suitability for writing UDP servers

From: Oleksiy Stashok <Oleksiy.Stashok_at_Sun.COM>
Date: Tue, 30 Oct 2007 16:16:25 +0100

Hello Radim,
>> If I understand the issue properly, you would like to have one packet per SelectionKey?
>>
> no, i would like to have one selection key per (client ip:client port:server ip:server port).
>
> statefull firewalls can do something like this and it can be possibly simulated in Java:
> Code something like ACCEPT for UDP:
>
> After receiving UDP packet on server socket, check own database of client ip/client port combos. If client ip/port combo is found in database it is probably
> safe to ignore packet because it should arrive on second channel too.
>
> If no known client is found, create new UDP channel and bind it to server ip,port (with addr reuse) and then connect() it to client ip/port. you will get
> new SelectionKey - unique to client
>
> This is a bit OS dependent because UDP packet from client can be received by both channels or just by newly created channel. Modern OSes should forward received UDP packet just to new channel but it needs some testing.
>
I investigated possibility of implementing such behavior.
Basically the main problem is that it's impossible (or I didn't find the
way) to retrieve remote address on server side udp socket, until UDP
packet is not read. Because
datagramChannel.socket().getRemoteSocketAddress() returns null for
server side Datagram channel. And only
datagramChannel.receive(ByteBuffer) returns SocketAddress.
So in case, if UDP packet will come to both channels - it means read
operation should be executed twice, which seems could lead to perf. issues.

As alternative I can think about implementing own SelectionKey
mechanism, so we will have own map of host:port -> SelectionKey
correspondence. And pass these custom SelectionKeys, when performing
server side UDP processing.

What do you think?

Thanks.
WBR,
Alexey.

>
>>> * at lot of places in code filters/other components are canceling
>>> SelectionKeys on io errors (such as UDP output buffer full). If they
>>> cancel SelectionKey, server socket is closed and nobody other
>>> can use server until server is restarted.
>>>
>> Hum, that would be a bug if that's the case. When the SelectionKey is
>> cancelled, it means the connection is either closed by the client of
>> something unexpected happens. Do you have a test case I can use to
>> reproduce the problem?
>>
> Its timing dependent. test case is like this:
> client creates UDP socket connect it to server, sends packet,closes socket.
> server reads packet,sends reply (UDP stack returns error because client closed socket), server closes socket
> and no other client can connect to it.
>
>
>>> * DefaultSelectionKeyHandler closes server socket after 30 secs of
>>> inactivity
>>>
>> Yes that's a design decision we took. You can disable the feature by doing:
>>
> you are closing listening socket if no client connects to TCP server in last 30
> seconds by default? Because in UDP case, it closes socket but Controller select
> loop is still running, so result is that nobody can connect to it anymore.
> While it can be good design decision to close client sockets after 30 seconds,
> it should not close server socket.
>
>
>> It close socket only when an exception happens. Are you seeing something
>> different? If yes, it means there is a bug :-)
>>
> UDPSelectorHandler needs
> protected Boolean isClient = false; field
> when running in client mode, don't create server socket, when running in
> server mode, never close sockets on errors.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>
>