wolfcastle
wolfcastle

Reputation: 5940

How can I configure the source port for a server using Netty to send UDP packets?

I have a server task that uses Netty for socket I/O. It binds to port MY_PORT and receives UDP messages from clients. It responds to these clients, sending messages back to the clients with a destination port of MY_PORT. Using wireshark, I see that the outgoing packets from my server also have a source port of MY_PORT. This all works fine.

The people in charge of the network between the server and clients are having some issues with a load balancer. They said it would help them out if the UDP messages my server sends to the clients had a different source port than the one used for a destination.

I've looked at the Netty API, but I'm not sure how I can do this. It seems that because I've bound to a local port, I must use that for outgoing packets as well?? Here's a stripped down version of my code.

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ConnectionlessBootstrap;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.channel.socket.nio.NioDatagramChannelFactory;

public class UdpServer {

    private final int port;
    private Channel serverChannel;

    public UdpServer( int port ) {
        super();
        this.port = port;
    }

    public void start() {
        NioDatagramChannelFactory serverChannelFactory =
            new NioDatagramChannelFactory( Executors.newCachedThreadPool(), 1 );
        ConnectionlessBootstrap serverBootstrap =
            new ConnectionlessBootstrap( serverChannelFactory );
        serverBootstrap.setPipelineFactory( new ChannelPipelineFactory() {
            @Override
            public ChannelPipeline getPipeline() {
                return Channels.pipeline( new SimpleChannelHandler() {
                    @Override
                    public void messageReceived( ChannelHandlerContext ctx,
                        MessageEvent e ) {
                        // TODO, handle message from client
                    }
                } );
            }
        } );
        serverBootstrap.setOption( "reuseAddress", Boolean.TRUE );
        final InetSocketAddress trafficAddress = new InetSocketAddress( port );
        serverChannel = serverBootstrap.bind( trafficAddress );
    }

    public void sendMessage( byte[] message, String clientIp )
        throws UnknownHostException {
        // TODO, how do I control the source port of this packet??
        SocketAddress address =
            new InetSocketAddress( InetAddress.getByName( clientIp ), port );
        ChannelBuffer buffer = ChannelBuffers.wrappedBuffer( message );
        serverChannel.write( buffer, address );
    }

}

Upvotes: 0

Views: 3381

Answers (2)

Jim Garrison
Jim Garrison

Reputation: 86774

You're already using bind() to set the local address. You can use connect() to connect to a specific destination port (a stretch of the "connect" concept). On a regular datagram socket you could include the remote port in the send request, but not if you're using write(). In that case you must use connect().

Upvotes: 2

user207421
user207421

Reputation: 311028

They said it would help them out if the UDP messages my server sends to the clients had a different source port than the one used for a destination.

This sounds like complete hooey to me. Net admins seem to have no idea about how source/destination ports are actually allocated. Even if the clients used system-allocated poets rather than a fixed port, which they probably should, the system could still allocate the same port number as the server is using.

However you could probably shut them up, or at least move them on to a different problem, by having the clients use system-allocated ports rather than a fixed port. Unless there is a client-side firewall of course ...

Upvotes: 0

Related Questions