jNetPcap sendPacket() function duplicating the frame - java

I would like to ask you a specific question: I'm trying to develop a software switch with the jNetPcap 1.4 library on Java 1.7, the goal is to have a program, that can forward packets received on port no. 1 to port no. 2 and vice versa (just on these two NIC-s).
I can see all the incoming packets on both of the interfaces, but when it comes to forwarding, I have a problem: if I send a packet on interface X with pcap.sendPacket(PcapPacket) the nextPacket() function inside the PcapPacketHandler() class will see it also, and will treat is a "new" packet, insted of just ignoring it, because it was sent by the same Pcap instance.
Is there any way to ignore the packets, that were sent by the pcap.sendPacket(PcapPacket) function (so they do not appear again in the nextPacket() function)?
I don't know much about the underlying winpcap library, but I'm sure SharpPcap in C# has this type of functionality. Doesn't jNetPcap have it also, or am I missing something?
Things I've tried:
Using pcap.inject() instead of pcap.sendPacket(), but my NIC doesn't
seem to support this function
Setting the capture direction to inbound only with
pcap.setDirection(Direction.IN) - this seems to have absolutely no
effect, the packets are captured just as before setting it.
Ps. unfortunately I have to write it in Java, if the jNetPcap library does not have this functionality, please, could you advise how to solve the problem? I'm thinking of buffering the sent packets to an array of some type and checking every newly detected packet to be the same as one packet in the array - but this seems to be a computationally complex solution.
Here's my sample code (not the whole, just the relevant pieces):
// Init
Pcap pcap = Pcap.openLive(devices.get(0).getName(), 64*1024, Pcap.MODE_PROMISCUOUS, 1000, errbuf);
...
PcapPacketHandler<String> jpacketHandler = new PcapPacketHandler<String>() {
public void nextPacket(PcapPacket packet, String user) {
// The duplicate packet that is sent in the sendAll() function also appears here
// Process the packet and add it to the forwarding buffer if needed
buffer.addPacket(packet);
}
}
// This is called in a separate thread, if some packets were added to the buffer
public void sendAll(){
while(buffer.hasNext() != 0){
pcap.sendPacket(buffer.getNextPacket());
}
}
Same goes for the second interface.
Thank you for your help in advance.

I realize this is an old and maybe not so popular topic, but I finally solved this by adding a buffer and constantly checking for duplicates. Since the code is complex, I decided to post the key functionality and how do I ignore the frame based on jnetpcap.com recommendation.
The code:
// we're inside the nextPacket(PcapPacket currentPacket, String user) method
buffer.lock();
for(int j = 0; j<buffer.size(); j++){
if(currentPacket.getCaptureHeader().caplen() == buffer.get(j).getCaptureHeader().caplen()
&& packet.size() == buffer.get(j).size()){
buffer.erasePacket(j);
return;
}
}
buffer.unlock();
// continue packet processing
Feel free to use it in your project.

Related

Handle multiple clients with one server

I try to get a connection to multiple clients using the Sockets in Java. Everything seems to work, but the problem is, that the server just listens to the first client. If there are multiple clients, the server can send them all messages, but he can just listen to the messages that came from the first client. I tried this all out (I'm at this problem since yesterday). So I'm pretty sure, that the fault has to be in the class "ClientListener".
Explanation:
There is a List with clients (connection to communicate with Strings). In the GUI there is a list, where I can choose, with which client I'd like to communicate. If I change the client, the variable currentClient (int) switches to another number
networkClients is an ArrayList, where all the different connections are "stored".
The first connected client is exactly the same as the other clients, there is nothing special about him. He is called, when the variable currentClient is set to 0 (per default). The variable-switching is working. Like I said, all the clients give me a response if I send them an order, but just networkClients.get(0) is heard by the server (ClientListener).
class ClientListener implements Runnable {
String request;
#Override
public void run() {
try {
while (networkClients.size() < 1) {
Thread.sleep(1000);
}
//***I'm pretty sure, that the problem is in this line
while ((request = networkClients.get(currentClient).getCommunicationReader().readLine()) != null) {
//***
myFileList.add(new MyFile(request));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
I hope someone can help me. I tried many things, but nothing worked.
EDIT: Like I wrote in the code example, is it possible that the while-loop isn't able to switch the number of "currentClient" (which is handled by another Thread)? I tested/simulated something similar in a testclass and the result was, that a while-loop of course can can update the state in it (meaning, that if a variable changes in the () of a while loop, it will of course be checked after every repeat).
You should take a look at multithreading.
Your server program should be made out of:
- The main thread
- A thread that handles new connections.
(Upon creating a new connection, start a new thread and pass the connection on to that thread)
- A thread for each connected client, listening to the each client separately
Take a look at some examples like: (1) (2)
I found the solution:
The Thread sits in the declared method I mentioned in the starting post (in the code snippet) and waits unlimited time for a new response of the client.
So changing the index of the list "networkClients" won't do anything, because nothing will happen there, until there is a new order sent by the client (which lets the thread go further).
So you need to implement an extra listener for each client.

How to create a poll system for IRC using Pirc

I'm a beginner java user, and beginning streamer on Twitch.tv. I have been working on developing an IRC bot all night that would streamline moderation on my channel (I want to have that level of customization that using a cookie cutter IRC bot can't give).
One thing that is stumbling me is poll creation. I have looked through the Pirc javadocs and there is no command as far as I can see that checks for messages sent by a channel op, which is crucial to keeping trolls from creating polls, and with my limited knowledge I do not know how to grab extra parameters from a message.
What I want is this:
!poll <question> <c1> <c2> <c3> <seconds>
Any help here? I will add you to my thanks screen on my outro for each stream.
From my quick look through the PIRC javadocs, it looks like the method you want is #onMessage(String channel,
String sender,
String login,
String hostname,
String message)
From here, you can get any information required. Now depending on how you're handling incoming messages, all you need to do it search for the command, which in this case is "!poll" which you'll receive from the message string. From there, you can further parse the information, and do what you want with it.
If you haven't been using them already, the javadocs for pirc are location here: http://www.jibble.org/javadocs/pircbot/index.html
As Jdsfighter said, you need to use the onMessage(...) method from the PircBot superclass. This method is called whenever a message is sent to your channel. I kinda assume you have understood this by now, as making the bot react to chat is alpha and omega when making an IRC bot.
When concerned with Moderators (Operators in IRC terms), the Twitch IRC servers behave in a way that isnt completely understood by PircBot, and I have not been successfull with the User.isOp(...) method from the User class. What I've found successfull is to include the following in my Bot class (not the main class):
Set<String> OPs = new HashSet<String>();
protected void onUserMode(String channel, String sourceNick, String sourceLogin, String sourceHostname, String recipient) {
recipient = recipient.split(" ")[2];
OPs.add(recipient);
}
This Method is called whenever you see a line begining with MODE in the console, like this one:
jtv MODE #channel +o moderatorName
Now, you need to make a method that is called whenever the message recieved starts with "!poll", and checks if the sender of the message is in the OPs Set.
Here's an outline for you, to be placed in the onMessage() method
if (message.toLowerCase().startsWith("!poll") {
if (OPs.contains(sender)) {
//TODO Add body
}
}
Now you just have to make some code that catches the rest of the line after "!Poll" and posts a message back to the channel about the different poll options.
You obviously need somewhere to store your alternatives and how many votes they get each, I suggest simply two arrays, one String[] and one int[].

Netty + ProtoBuffer: A few communication messages for one connection

While reading the Netty tutorial, I've found a simple description of how to integrate Netty and Google Protocol Buffers. I've started to investigate its example (because there is no more information in the documentation) and written a simple application like the example local time application. But this example is using static initialization in PipeFactory Class, e.g.:
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.handler.codec.protobuf.ProtobufDecoder;
import org.jboss.netty.handler.codec.protobuf.ProtobufEncoder;
import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
import static org.jboss.netty.channel.Channels.pipeline;
/**
* #author sergiizagriichuk
*/
class ProtoCommunicationClientPipeFactory implements ChannelPipelineFactory {
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline p = pipeline();
p.addLast("frameDecoder", new ProtobufVarint32FrameDecoder());
p.addLast("protobufDecoder", new ProtobufDecoder(Communication.DataMessage.getDefaultInstance()));
p.addLast("frameEncoder", new ProtobufVarint32LengthFieldPrepender());
p.addLast("protobufEncoder", new ProtobufEncoder());
p.addLast("handler", new ProtoCommunicationClientHandler());
return p;
}
}
(Please take a look at line p.addLast("protobufDecoder", new ProtobufDecoder(Communication.DataMessage.getDefaultInstance()));)
and just one factory can be created (as I understand) for ClientBootstrap class, I mean bootstrap.setPipelineFactory() method. So, in this situation I can use ONE message to send to server and ONE message to receive from server and it is bad for me, and I think not just for me :( How can I use different messages to and from for just one connection?
Perhaps I can create a few protobufDecoder like this
p.addLast("protobufDecoder", new ProtobufDecoder(Communication.DataMessage.getDefaultInstance()));
p.addLast("protobufDecoder", new ProtobufDecoder(Communication.TestMessage.getDefaultInstance()));
p.addLast("protobufDecoder", new ProtobufDecoder(Communication.SrcMessage.getDefaultInstance()));
or other techniques?
Thanks a lot.
I've found thread of author of netty in google groups and understood that I have to change my architecture or write my own decoder as I wrote above, So, Start to think what way will be easy and better.
If you are going to write your own codecs anyway, you might want to look at implementing the Externalizable interface for custom data objects.
Serializable is low-effort, but worst performance (serializes everything).
Protobuf is a good trade-off between effort and performance (requires .proto maintenance)
Externalizable is high effort, but best performance (custom minimal codecs)
If you already know your project will have to scale like a mountain goat, you may have to go the hard road. Protobuf is not a silver bullet.
Theoretically this can be done by modifying the pipeline for each incoming message to suit the incoming message. Take a look at the port unification example in Netty.
Sequence would be:
1) In frame decoder or another "DecoderMappingDecoder" you check the message type of the incoming message
2) Modify the pipeline dynamically as shown in the example
But why not use different connections and follow this sequence:
1) Add other decoders in pipeline based on the incoming message only once.
2) Add the same instance of channel upstream handler as the last handler in the pipeline, this way all messages get routed to the same instance, which is almost like having a single connection.
the problem is that there is no way to distinct two different protobuf messages from each other in binary format. But there is a way to solve it within the protobuf file:
message AnyMessage {
message DataMessage { [...] }
optional DataMessage dataMessage = 1;
message TestMessage { [...] }
optional TestMessage testMessage = 2;
message SrcMessage { [...] }
optional SrcMessage srcMessage = 3;
}
optional fields that are not set produce no overhead. Additionally you can add an Enum, but it is just a bonus.
The issue is not quite a Netty limitation or encoder/decoder limitation. The problem is that Google Protocol Buffers are offering just a way to serialize/deserialize objects, but is not provide a protocol. They have some kind of RPC implementation as part of standard distribution, but if you'll try to implement their RPC protocol then you'll end up with 3 layers of indirection.
What I have done in one of the project, was to define a message that is basically an union of messages. This message contains one field that is Type and another field that is the actual message. You'll still end-up with 2 indirection layers, but not 3. In this way the example from Netty will work for you, but as was mention in a previous post, you have to put more logic in the business logic handler.
You can use message tunneling to send various types of messages as payload in a single message.
Hope that helps
After long research and suffering...
I came up with idea of using composition of messages into one wrapper message. Inside that message I use oneof key to limit the number of allowed objects to the only one. Checkout the example:
message OneMessage {
MessageType messageType = 1;
oneof messageBody {
Event event = 2;
Request request = 3;
Response response = 4;
}
string messageCode = 5; //unique message code
int64 timestamp = 6; //server time
}

Design(Classes, methods, interfaces) of real time applications(server/client)

IĀ“ve been looking for a good book or article about this topic but didnt find much. I didnt find a good example - piece of code - for a specific scenario. Like clients/server conversation.
In my applicationĀ“s protocol they have to send/recieve messages. Like:
Server want to send a file to a client
Client can accpet or no,
if he accepts, server will send bytes over the same connection/socket.
The rest of my application all uses blocking methods, server has a method
Heres what I did:
Server method:
public synchronized void sendFile(File file)
{
//send messsage asking if I can send a file
//block on read, waiting for client responde
//if client answers yes, start sending the bytes
//else return
}
Client methods:
public void reciveCommand()
{
//read/listen for a command from socket
//if is a send file command handleSendFileCommand();
//after the return of handleSendFileCommand() listen for another command
}
public void handleSendFileCommand()
{
//get the file server want to send
//check if it already has the file
//if it already has, then send a command to the socket saying it already has and return
//else send a command saying server can send the file
//create a FileInputStream, recive bytes and then return method
}
I am 100% sure this is wrong because, there is no way server and clients would talk bidirecional, I mean, when server wants to send a command to a server, they have to follow an order of commands until that conversation is finished, only then, they can send/recive another sequence of commands. Thats why I made all methods that send requests synchronized
It didnt took me a lot of time to realize I need to study about design patterns for that kind of application...
I read about Chain of Responsibility design pattern but I dont get it how can I use it or another good design pattern in that situation.
I hope someone can help me with some code example-like.
Thanks in advance
synchronized keyword in Java means something completely different - it marks a method or a code block as a critical section that only single thread can execute at a time. You don't need it here.
Then, a TCP connection is bi-directional on the byte-stream level. The synchronization between the server and a client is driven by the messages exchanged. Think of a client (same pretty much applies to the server) as a state machine. Some types of messages are acceptable in the current state, some are not, some switch the node into different state.
Since you are looking into design patterns, the State pattern is very applicable here.

Send ProtocolBuffer Message.Builder to another machine via RMI

I have the following pesudocode:
public void sendPB(ObjectId userId, Message.Builder mb) {
if (userId is logged in to server) {
set mb.ackId to random chars
lookup socket and send mb.build()
}
else {
forward message to user's server via RMI
}
}
The problem is Message.Builders do not implement Serializable, so you cannot send it directly via RMI.
Is there an easy way to do this?
I've tried building partial PB from the builder and sending that over, but in order to reconstruct it you need to know the type or the Descriptor. Descriptor doesn't implement Serializable either.
Thanks
Any reason you can't call build(), get a Message, and send it across in whatever the correct format is (e.g., toString()). At the other end, you can inflate it back into a Message, and make it back into a builder with toBuilder() if that's required.
You may also just convert the message to binary format and send that.
Maybe I'm misunderstanding -- the whole point of ProtocolBuffers is to get Messages into a wire representation, so there are a number of ways to do that (most of which are either Serializable or trivially wrapped to be.)
I got it working... I had to include a typeID field in the RMI message. Then, I could take the typeID and resolve it to a Message Builder, and then mergeFrom the bytes of the partially built message.

Categories