There are quite a couple of related questions (e.g. Java Socket specify a certain network interface for outgoing connections ) however I couldn't find a satisfying i.e. practical solution to my problem:
On my target (Linux) platform there are multiple network interfaces (eth0...ethN) from which a Server S is reachable. The default route is normally via eth0, however I'm trying to connect S via e.g. eth4 using
new java.net.Socket(IP_of_S, targetport, IP_of_eth4, srcport)
or
sock.bind( eth4_SocketAddress );
sock.connect( S_SocketAddress );
In this example case the IP of eth4 is assigned correctly but traffic is still going out trough the interface of the default route. I've learned this is due to the the "weak end system model" RFC 1122. However I'm wondering whether there's still a Java-based solution to achieving my original goal or whether I have to trigger external iptables or route calls from my program.
(BTW: The outgoing interface needs to be chosen dynamically at runtime, i.e. my program closes the connection and tries to reconnect using a different outbound interface quite frequently.)
As far as I know, you cannot choose the outgoing interface without some routing table setup.
In my opinion, the best solution is to set up a bunch of source-specific routes, routes that match on the source address of a packet, and bind to a given source address in order to select the route (as you already do). There are two ways of achieving that:
use ip rule and multiple routing tables — this is described in http://lartc.org/howto/lartc.rpdb.html ;
use ip route add ... from .... As far as I know, this only works for IPv6, but avoids the complexity of multiple routing tables.
You'll find some background about source-specific routing in https://arxiv.org/pdf/1403.0445v4.pdf (disclaimer, I'm a co-author).
Related
This question is a follow up to:
Akka Routing: Reply's send to router ends up as dead letters
I'm facing the same problem.
It is given in the answer that
"Note that different code would be needed if the routees were
not children of the router, i.e. if they were provided when the router was created."
I want to know What is that different code and how does it work? And is there any other way to communicate with the Router other than this method?
It'd be good if exlpained with code snippets or links to projects where it is used.
I'm a relatively novice programmer and newish to java, and I've been tasked with creating a distributed system that runs two types of applications; a single 'Server/Router' and as many Client-Server 'Nodes' as desired.
-The Server/Router will maintain a table of client connection info
-The Nodes will each send connection info when they spawn
-The Node A can request File F from Node B
---This Request is sent to the router, which looks up connection info for B and sends a request for F
---B begins streaming F to the router, which in turn streams F to A
That's the general idea. It sounds like it would be fairly simple if it weren't for the fact that I've never done ANY distributed computing before... So my question isn't one of how to correct code, but whether my design will work (and if it will not, how I might correct it)
So my idea is to create a public class AVRouter, another class AVNodeInfo, and a third class ConnectionMap; AVRouter will have a collection of AVRouterInfo objects which contain a name, port number, and IP address for each node. It will also have a Queue of ConnectionMap objects, which I'll get to shortly.
AVRouter will have a ServerSocket dedicated to receiving connection info from Nodes when they start up and populating its AVNodeInfo table with said data. It will have another port for file requests; it will use the connection info for the requester and the responder to generate a ConnectionMap object, which it will add the the queue.
The idea being that while there are ConnectionMaps in the queue, it will use the first one to facilitate a transfer.
The last class, AVNode, is much simpler; on spawning it sends its info to the Router, and then it waits for user input to name another node and a file it wishes to request from that node. It will send a completed request to the Router when one is available.
Logic for handling the AVNodeInfo table will probably just be handled with timeouts-if it's been X time since a node has made a request, the node will terminate on its own and the table will delete it from the table on its own... this is a small-scale proof-of-concept type project so it's not really within to scope to handle this nitty-gritty just yet.
So I actually have two questions:
1) Will this design be fine, or should it be improved?
2) How exactly does one handle streaming data from source A through router B to destination C without actually complete transferring from A to B, then from B to C?
I hope this question is within StackOverflow's scope; I know it's design rather than code, but I believe it's specific enough.
The principal concept sounds very ok and is probably the most easy to implement (with the least pitfalls). Its practically a standard approach.
You might want to consider, instead of sending a file from node to server and then forward to the requesting node, to have the nodes connect directly with each other. Node A would just ask the server where is file F and then connect directly to node B.
(that should reduce network load, since data travels a shorter route). But it adds quite some complexity (each node must be able to reach any other node and that makes each node a server). A composite approach would be to try direct connection and if that fails fall back to the via-server method.
You can just implement your original concept and when you have it working, see if you want/need that extension.
Edit: I would probably fuse NodeInfo and Connection (connection as a member of NodeInfo) - the server should have exactly one connection to each node (or if using multiple connections, have NodeInfo hold a collection of the open connections to that specific node).
EDIT: To add to the workability of your concept. Its generally what P2P sharing programs like BitTorrent implement. The "Tracker" acts as the initial "Router" telling each client about other peers. Peers then use direct connections to talk to each other. So its practical identical to what you've come up with, only there is not data traffic using the Server/Router as a bridge (for obvious bandwidth concerns, and it would contradict the P2P idea).
I want to create chat server and I need to be able to do some things like clear the screen of a specified client, I thought about it and I figured that it would be a good idea if I would send a keyword to the client:
clientSide eg:
if((sporocilo = bufferedReader.readLine()) != null){
if(sporocilo.equals("clearTheScreen"{
object.clearMyScreen
}
}
However there are a lot of commands and the source code would be huge, plus once a client figures out the keyword he could exploit it, how could I do that in another, better way?
Take any example like FTP. Port 20 is used for default data and port 21 is used for Control(authentication etc).And different port mean different socket. After all socket is IP + Port no.
Same is in your case. Use different ports for actual chat data and your service instructions(like clear screen though i don't see why server must clear clients screen). Also instead of string commands like "clearTheScreen" use service ID's and keep a mapping of service ID to functions to be executed. Because if you keep simple string with names like "clear" or "password" with it then it will be easy for other to manipulate data(if it is not encrypyted ofcourse which is another good way to send data).
I have a chat program implemented in Java. The client can send lots of different types of information to the server (i.e, Joins the server and sends username, password; requests a private chat with another user on the server, disconnects from the server, etc).
I'm looking for the correct way to have the server/client differentiate between 'text' messages that are just meant to be chat text messages sent from one client to the others, and 'command' messages (disconnect, request private chat, request file transfer, etc) that are meant for the server or the client.
I see two options:
Use serialized objects, and determine what they are on the receiving end by doing an 'instanceof'
Send the data as a byte array, reserving the first N bytes of the array to specify the 'type' of the incoming data.
What is the 'correct' way to do this? How to real protocols (oscar, irc) handle this situation?
I've googled around on this topic and only found examples/discussions centering on simple java chat applications. None that go into detail about protocol design (which I ultimately intend to practice).
Thanks to any help...
Second approach is much better, because serialization is a complex mechanism, that can be easily used in a wrong way (for example you may bind yourself to internal content of a concrete serialized class). Plus your protocol will be bound to JVM mechanism.
Using some "protocol header" for message differentiation is a common way in network protocols (FTP, HTTP, etc). It is even better when it is in a text form (people will be able to read it).
You typically have a little message header identifying the type of content in all messages, including standard text/chat messages.
Either of your two suggestions are fine. (In your second approach, you probably want to reserve some bytes for the length of the array as well.)
I'm writing an application server that will receive SIP and DNS messages from the network.
When I receive a message from the network, I understand from the documentation that at first, I get a ChannelBuffer. I would like to determine which kind of message has been received (SIP or DNS) and to decode it.
To determine the message type, I can dedicate port to each type of message, but I would be interested to know if there exist another solution for that. My question is more about how to decode the ChannelBuffer.
Is there a ChannelHandler provided by Netty to decode SIP or DNS messages? If not, what would be the right place in the type hierarchy to write my custom ChannelHandler?
To illustrate my question, let's take as example the HttpRequestDecoder, the hierarchy is:
java.lang.Object
org.jboss.netty.channel.SimpleChannelUpstreamHandler
org.jboss.netty.handler.codec.frame.FrameDecoder
org.jboss.netty.handler.codec.replay.ReplayingDecoder<HttpMessageDecoder.State>
org.jboss.netty.handler.codec.http.HttpMessageDecoder
org.jboss.netty.handler.codec.http.HttpRequestDecoder
Also, do I need to use two different ChannelHandler for decoding and encoding, or is there a possibility to use a single ChannelHandler for both?
Thanks
If you really have a requirement for port unification (an example here), i.e. receiving different protocols on the same port, then you would have to detect the protocol in a handler and take appropriate actions. Could be as simple as inserting different handlers in the pipe line.
However, I find it very improbable that SIP and DNS would share the same port, hence no need to complicate matters.
I haven't seen a SIP decoder/encoder for Netty, but depending on what you want to do with the message, the HTTP decoder is a a very good starting point (and could be made simpler since chunking is not supported in SIP).
I would strongly recommend not to try to combine DNS and SIP decoding in one handler (or any other combination for that matter). Keep the handlers as simple and coherent as possible. Combine handlers instead, if needed.