What connection except for network connection can Jetty Endpoint represents - java

https://www.eclipse.org/jetty/javadoc/9.4.8.v20171121/org/eclipse/jetty/io/EndPoint.html#getLocalAddress--
From this documentation, getLocalAddress will return null if the endpoint does not represent a network connection. So under what circumstances the endpoint represents connection other than network connection? And what type of connections are they?

FastCGI, UnixSocket, and LocalConnector usages are some examples of connections that have an EndPoint but are not network connections that have a java.net.InetSocketAddress available to represent the remote endpoint.
Note: Jetty 10 is considering changing that API from returning java.net.InetSocketAddress to just java.net.SocketAddress (as all three of the above can return flavors of SocketAddress)
FastCGI - FastCgiSocketAddress - points to the directory on disk
UnixSocket - UnixSocketAddress - points to the socket file (usually on disk)
LocalConnector - LocalSocketAddress - an implementation with no public methods (as this is a purely in-memory connection)
Other projects have variants of in-memory or mock connectors that would also represent an EndPoint without a InetSocketAddress.

Related

Can a PINGREQ message be used by a gateway to update a network address in MQTTSN

Im using an MQTTSN Gateway Version 1.2 from;
https://github.com/simon622/mqtt-sn
I notice that a when a client connection goes to sleep and then subsequently wakes up, its IP address may well have changed on the network. When the next PINGREQ message is sent by a client, the gateway is unable to establish its identity from the network address and so the session simply times out.
Is there anyway of updating the network address in this scenario to tie it back to the original session without having the overhead of a new CONNECT?
I tried issuing a new PINGREQ, but the gateway was unable to link the new network address to an existing gateway session.
You're correct in stating that a client may well recycle their IP address during a network event (ie. a network stack power down, or roaming between cells on a cellular network). These events typically require a completely new CONNECT to be issued in order to re-authenticate with a gateway, since typically in SN UDP implementations, the network address is used as part of the identification mechanism. You can CONNECT(clean=false) to maintain session state.
Allowing a client to re-establish (or bind to an existing) session using a PINGREQ alone (with the presence of a clientId) would be very insecure and would present an easy attack vector for session hijacking.
Hope this helps clarify things.

Android VpnService Configuration

I am trying to use the VpnService from android to setup a simple tun device on the client side and on the receiving side I have a c++ server running.
I am having a lot of problems with the VpnService. This is what I need,
I need ALL packets outbound from the Android phone to be routed to the tun device, and in the program I route it through a Datagram channel to the server. When I send a string, it works fine, but when I send other data through this Datagram channel, i don't see any UDP packets in Wireshark :\
Also, I am new to Java and Datagram channels. Here Is my code
//To establish the tunnel
builder.setSession("MyVPNService")
.addAddress("192.168.56.0", 32)
.addDnsServer("8.8.8.4")
.addRoute("0.0.0.0", 1);
mInterface=builder.establish();
What exactly are the above configurations doing? Isn't a tun device supposed to have ONE IP(from my experience from doing it on linux), then what is ""192.168.56.0", 32". Also when i try to add a route "0.0.0.0", 0 the whole android phone hangs and restarts :\
while (true) {
int length;
// Read the outgoing packet from the input stream.
length=in.read(packet_bytes);
//int length = in.read(packet.array());
if (length > 0) {
// Write the outgoing packet to the tunnel.
//packet.limit(length);
//tunnel.send(packe,server);
tunnel.send(packet,server);
packet.put(packet_bytes,0,length);
tunnel.write(packet);
packet.clear();
}
Thread.sleep(200);
// Read the incoming packet from the tunnel.
length = tunnel.read(packet);
if (length > 0) {
out.write(packet.array(), 0, length);
packet.clear();
// If we were sending, switch to receiving.
}
Thread.sleep(200);
}
This is the part where I take it from interface and put it on the other.
First, let me start by explaining Builder configuration above.
builder.setSession("MyVPNService") // This one is optional.
.addAddress("192.168.56.0", 32) // This is used to assign interface address. First param is IP address, and second in prefix length. "Prefix" length is also commonly known as subnet mask.
.addDnsServer("8.8.8.4") // This configures the DNS network for VPN network. For ex - All DNS resolutions would go to 8.8.8.4:53. Note that the DNS request packets gets routed through the tun interface.
.addRoute("0.0.0.0", 1); // This controls the IP addresses which gets routed through tun interface.
Note - that tun interface can support multiple address families (IPv4/IPv6). As an example, you can assign multiple interface addresses (say a v4, a v6, or two v6 addresses, or whatever combo).
Similarly, you can add routes that you want your VPN to handle. Now, the main question is how do you decide which routes should my VPN handle?
Well there are bunch of options.
Route everything - Adding 0.0.0.0/0 (for IPv4), and ::/0 (for IPv6) would route traffic for all destinations through VPN (Note: 0.0.0.0/0 represents entire IPv4 range i.e. 0.0.0.0 to 255.255.255.255).
Route specific routes - You would have typically noticed that talking to IoT devices does not work when VPN is running. That is typically due to "route everything" config setup which breaks local networking (ex - chromecast). So, excluding link local traffic requires doing some math that involves subtracting link local subnets from above subnets (0.0.0.0/0, ::/0 (for v6 local subnets)). The math involved is not very straightforward which makes this option a lot more complex. As for what constitutes link local subnets, here is a list from wikipedia, and from IETF for IPv4 and IPv6 special addresses.
That said, here are some answers to your questions.
I need ALL packets outbound from the Android phone to be routed to the tun device
See "route everything" above.
Isn't a tun device supposed to have ONE IP?
An interface on linux can have multiple interface addresses assigned to it from different address families.
Then what is "192.168.56.0", 32".
As explained above, first part is the IP address, and second defines the subnet mask. Also see CIDR notation.
Also when I try to add a route "0.0.0.0", 0 the whole android phone hangs and restarts.
0.0.0.0/0 means entire IPv4 address space will get routed through the VPN. Typically, a VPN cannot handle link local traffic as I have mentioned above. So, you will have to exclude certain local subnets (see links above). As for phone hanging and restarting, I'm not sure if that has anything to do with the VPN unless VPN is not handling traffic correctly (which would lead networking related apps to break).

FTPClient Pool - Java

I am writing a Rest Service that connects to an FTP server to read some files, then do some operations over the read data to serve the service request. I am using Apache commons FTPClient.
As a temporary solution, I am creating an FTPClient object - then connecting it - and then logging in with the credentials - inside a method (the client is local to this method - doing this as FTPClient is not thread safe) in my data access layer and then disconnecting it before coming out of the methods(ie.. after reading the file). The issue is, FTPClient is taking some 3-7 seconds for logging in which is very high. So I am thinking of implementing an FTPClientPool that can provide an already prepared client in the data access method.
Do any such ClientPools already exist?
If yes, then what one should I opt for?
If no, the difficulty in implementing is once created and connected, How long does an apache FTPClient stay alive? for infinite time?? (what I mean is what is the default keep alive time for an FTPClient - idle time after which client gets disconnected - coz I see various kind of times in the java docs. :( ) And next questions is How do you keep it alive always?? (may be sending the NOOPS after regular intervals in a separate thread??) Any kind of help regarding how should I move forward is really helpful.
Thanks & Regards
Idle timeout for clients is generally determined server side.
Here's some of the more non obvious client parameters:
soTimeout - Determines how long the client blocks waiting for a message. Generally you poll a socket every so often and this determines how long you wait during a poll.
soLinger - Determines how long to keep the connection after close() has been called.
From my experience of using FTP, they normally just reconnect if the connection closes - it's not normally vital to have a constant uninterrupted connection unlike in other applications.
What are you using FTP for - it's normally not that time critical a service ...
As for ClientPools, I happened to write a demo project.
commons-pool-ftp
I am getting a little bit annoyed by the ftp protocol,
in our experience, it would meet broken pipe when testing on the client that just getting from the pool.
testOnBorrow=true
Configure
protected static ThreadLocal<FTPClient> ftpClientContainer = new
ThreadLocal<>();
Then use:
//login() will be your login method to FTP:
ftpClientContainer.set(ftpLogin());
Then in each method add:
FTPClient ftpClient = ftpClientContainer.get();
and finely when done:
//ftpDisconnect () will be your disconnect method to FTP:
ftpDisconnect(ftpClientContainer.get());

How to refuse incoming connections in Netty?

I have a Netty TCP server, and I want to reject/refuse incoming connection attempts selectively (based on their remote address). I guess I have to use ServerBootstrap.setParentHandler(ChannelHandler), but what do I do in the ChannelHandler? What event am I handling? How do I refuse the connection?
As Norman said, there is no way to refuse the connection, but you can close it immediately by adding a Netty's IpFilterHandler to server pipeline as the first handler. It will also stop propagating the upstream channel state events for filtered connection too.
#ChannelHandler.Sharable
public class MyFilterHandler extends IpFilteringHandlerImpl {
private final Set<InetSocketAddress> deniedRemoteAddress;
public MyFilterHandler(Set<InetSocketAddress> deniedRemoteAddress) {
this.deniedRemoteAddress = deniedRemoteAddress;
}
#Override
protected boolean accept(ChannelHandlerContext ctx, ChannelEvent e, InetSocketAddress inetSocketAddress) throws Exception {
return !deniedRemoteAddress.contains(inetSocketAddress);
}
}
if you have list of patterns of IP address to block, you can use IpFilterRuleHandler,
//Example: allow only localhost:
new IPFilterRuleHandler().addAll(new IpFilterRuleList("+n:localhost, -n:*"))
If you have several network interfaces and you want to accept connections from one interface only you just need to set the local address in ServerBootstrap. This may be enough if your server is running in a machine that's connected to several networks and you want to serve only one of them. In this case any connection attempts from the other networks would be refused by the OS.
Once you have a connection in the application layer it's too late to refuse it. The best you can do is close it immediately.
This is enough if for example you want the server available only on localhost and invisible to the outside world: the loopback network 127.0.0.0/8 is served by a separate interface.
After having looked at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink in the Netty sources, I am fairly certain that Netty accepts all incoming connections, and there is no way to refuse them (but, of course, they can be closed after being accepted).

Java outgoing TCP connection failover based on multiple DNS results

If I make a connection using new Socket("unit.domain.com", 100) and the unit.domain.com DNS record has multiple IP addresses in the A record.. In the event of a failed connection, Does Java automatically connect to one of the other addresses in the list like the browser does? or does that have to be implemented manually?
No!
Creating a socket via new Socket(String, int) results in a resolving like that
addr = InetAddress.getByName(hostname);
which is a shortcut for
return InetAddress.getAllByName(host)[0];
The address resolution is performed in the Socket c-tor.
If you have to reconnect (failover) use the result returned by InetAddress.getAllByName(host), randomize (or use round-robin) and connect to the necessary addresses.
Edit: also if you are going to need to connect with some likely failure, you'd be better off using connect method of the Socket class with a timeout. Also make sure you close even failed sockets (and esp. channels) since they may leak a FD on *Nix.

Categories