Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple STUN client in java

Tags:

java

stun

I have found several java STUN implementations

Java and Which Stun libraries i should use?

There is

  • JSTUN: http://jstun.javawi.de/
  • STUN: http://java.net/projects/stun

See also: STUN, TURN, ICE library for Java

But it is jars with many classes. I wish to find something simple in form of single method or at least single small class. Like following python code.

https://github.com/jtriley/pystun/blob/develop/stun/init.py

Reasonable answer why STUN in Java is so huge is also acceptable.

like image 447
Max Avatar asked Dec 15 '22 17:12

Max


1 Answers

Reasonable answer why STUN in Java is so huge is also acceptable.

It's a reasonable question. 99% of what STUN is just a simple echo/response protocol for a client to self-discover the IP and port mapping as a result of NAT between it and the public internet. Having built a STUN library in C++, I have some insight.

Let's think about what is required of a STUN library:

  • A message writer that generates the STUN messages with an attribute field schema that not only allows for fields to appear in any order, it also allows for custom attributes to be added as well.

  • A message parser that can read such messages back and convert a data structure reasonable for code to use. It needs to do this securely and avoid unhandled exceptions.

  • Socket networking code to send/receive such messages. And STUN servers are technically required to listen on 2 IPs and 2 ports, so that makes the networking code for the server a bit more complex.

  • If we just care about binding requests and binding responses, we'd be done. But the STUN RFCs also define a set of NAT classification tests. So additional state machine logic is needed to make any such library complete.

  • And if the STUN library is going to go all the way with the security options afforded by the protocol, it would need some amount of crypto code for hashing and signing of messages

So combining all this into a library that anyone can use for all the different purposes of STUN including mapped address discovery, NAT classification, and ICE negotiation, it starts to get big quick.

You could easily just roll some socket code that hardcodes the bytes of a binding request and then some hacked up parsing to parse the response. That might meet your own needs, but a well established open source library would never be written this way.

JSTUN is a good start. I've shared some interop and bug fixing code with the original author. He doesn't actively maintain it, but it's a good implementation of RFC 3489. I even hacked it up once to run on Android.

To generate a STUN binding request in JSTUN.

MessageHeader sendMH = new MessageHeader(MessageHeader.MessageHeaderType.BindingRequest);
sendMH.generateTransactionID();

// add an empty ChangeRequest attribute. Not required by the standard, but JSTUN server requires it
ChangeRequest changeRequest = new ChangeRequest();
sendMH.addMessageAttribute(changeRequest);

byte[] data = sendMH.getBytes();

// not shown - sending the message

Then to parse the response back:

byte [] receivedData = new byte[500];

// not shown - socket code that receives the messages into receivedData
receiveMH.parseAttributes(receivedData);
MappedAddress ma = (MappedAddress) receiveMH.getMessageAttribute(MessageAttribute.MessageAttributeType.MappedAddress);    

Then combine the above with some socket code. The best example of combining the above with socket code can be found in the DiscoveryTest.java source file. You really just need the code in the test1() method of this class.

like image 189
selbie Avatar answered Jan 06 '23 12:01

selbie