Unsupported library that attempts to punch holes through NAT
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

BindingLifetimeTest.java 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. * This file is part of JSTUN.
  3. *
  4. * Copyright (c) 2005 Thomas King <king@t-king.de> - All rights
  5. * reserved.
  6. *
  7. * This software is licensed under either the GNU Public License (GPL),
  8. * or the Apache 2.0 license. Copies of both license agreements are
  9. * included in this distribution.
  10. */
  11. package de.javawi.jstun.test;
  12. import java.util.logging.*;
  13. import java.util.*;
  14. import java.io.*;
  15. import java.net.*;
  16. import de.javawi.jstun.attribute.*;
  17. import de.javawi.jstun.header.*;
  18. import de.javawi.jstun.util.UtilityException;
  19. public class BindingLifetimeTest {
  20. private static Logger logger = Logger.getLogger("de.javawi.stun.test.BindingLifetimeTest");
  21. String stunServer;
  22. int port;
  23. int timeout = 300; //ms
  24. MappedAddress ma;
  25. Timer timer;
  26. DatagramSocket initialSocket;
  27. // start value for binary search - should be carefully choosen
  28. int upperBinarySearchLifetime = 345000; // ms
  29. int lowerBinarySearchLifetime = 0;
  30. int binarySearchLifetime = ( upperBinarySearchLifetime + lowerBinarySearchLifetime ) / 2;
  31. // lifetime value
  32. int lifetime = -1; // -1 means undefined.
  33. boolean completed = false;
  34. public BindingLifetimeTest(String stunServer, int port) {
  35. super();
  36. this.stunServer = stunServer;
  37. this.port = port;
  38. timer = new Timer(true);
  39. }
  40. public void test() throws UtilityException, SocketException, UnknownHostException, IOException, MessageAttributeParsingException, MessageAttributeException, MessageHeaderParsingException {
  41. initialSocket = new DatagramSocket();
  42. initialSocket.connect(InetAddress.getByName(stunServer), port);
  43. initialSocket.setSoTimeout(timeout);
  44. if (bindingCommunicationInitialSocket()) {
  45. return;
  46. }
  47. BindingLifetimeTask task = new BindingLifetimeTask();
  48. timer.schedule(task, binarySearchLifetime);
  49. logger.finer("Timer scheduled initially: " + binarySearchLifetime + ".");
  50. }
  51. private boolean bindingCommunicationInitialSocket() throws UtilityException, IOException, MessageHeaderParsingException, MessageAttributeParsingException {
  52. MessageHeader sendMH = new MessageHeader(MessageHeader.MessageHeaderType.BindingRequest);
  53. sendMH.generateTransactionID();
  54. ChangeRequest changeRequest = new ChangeRequest();
  55. sendMH.addMessageAttribute(changeRequest);
  56. byte[] data = sendMH.getBytes();
  57. DatagramPacket send = new DatagramPacket(data, data.length, InetAddress.getByName(stunServer), port);
  58. initialSocket.send(send);
  59. logger.finer("Binding Request sent.");
  60. MessageHeader receiveMH = new MessageHeader();
  61. while (!(receiveMH.equalTransactionID(sendMH))) {
  62. DatagramPacket receive = new DatagramPacket(new byte[200], 200);
  63. initialSocket.receive(receive);
  64. receiveMH = MessageHeader.parseHeader(receive.getData());
  65. receiveMH.parseAttributes(receive.getData());
  66. }
  67. ma = (MappedAddress) receiveMH.getMessageAttribute(MessageAttribute.MessageAttributeType.MappedAddress);
  68. ErrorCode ec = (ErrorCode) receiveMH.getMessageAttribute(MessageAttribute.MessageAttributeType.ErrorCode);
  69. if (ec != null) {
  70. logger.config("Message header contains an Errorcode message attribute.");
  71. return true;
  72. }
  73. if (ma == null) {
  74. logger.config("Response does not contain a Mapped Address message attribute.");
  75. return true;
  76. }
  77. return false;
  78. }
  79. public int getLifetime() {
  80. return lifetime;
  81. }
  82. public boolean isCompleted() {
  83. return completed;
  84. }
  85. public void setUpperBinarySearchLifetime(int upperBinarySearchLifetime) {
  86. this.upperBinarySearchLifetime = upperBinarySearchLifetime;
  87. binarySearchLifetime = ( upperBinarySearchLifetime + lowerBinarySearchLifetime ) / 2;
  88. }
  89. class BindingLifetimeTask extends TimerTask {
  90. public BindingLifetimeTask() {
  91. super();
  92. }
  93. public void run() {
  94. try {
  95. lifetimeQuery();
  96. } catch (Exception e) {
  97. logger.config("Unhandled Exception. BindLifetimeTasks stopped.");
  98. e.printStackTrace();
  99. }
  100. }
  101. public void lifetimeQuery() throws UtilityException, MessageAttributeException, MessageHeaderParsingException, MessageAttributeParsingException, IOException {
  102. try {
  103. DatagramSocket socket = new DatagramSocket();
  104. socket.connect(InetAddress.getByName(stunServer), port);
  105. socket.setSoTimeout(timeout);
  106. MessageHeader sendMH = new MessageHeader(MessageHeader.MessageHeaderType.BindingRequest);
  107. sendMH.generateTransactionID();
  108. ChangeRequest changeRequest = new ChangeRequest();
  109. ResponseAddress responseAddress = new ResponseAddress();
  110. responseAddress.setAddress(ma.getAddress());
  111. responseAddress.setPort(ma.getPort());
  112. sendMH.addMessageAttribute(changeRequest);
  113. sendMH.addMessageAttribute(responseAddress);
  114. byte[] data = sendMH.getBytes();
  115. DatagramPacket send = new DatagramPacket(data, data.length, InetAddress.getByName(stunServer), port);
  116. socket.send(send);
  117. logger.finer("Binding Request sent.");
  118. MessageHeader receiveMH = new MessageHeader();
  119. while (!(receiveMH.equalTransactionID(sendMH))) {
  120. DatagramPacket receive = new DatagramPacket(new byte[200], 200);
  121. initialSocket.receive(receive);
  122. receiveMH = MessageHeader.parseHeader(receive.getData());
  123. receiveMH.parseAttributes(receive.getData());
  124. }
  125. ErrorCode ec = (ErrorCode) receiveMH.getMessageAttribute(MessageAttribute.MessageAttributeType.ErrorCode);
  126. if (ec != null) {
  127. logger.config("Message header contains errorcode message attribute.");
  128. return;
  129. }
  130. logger.finer("Binding Response received.");
  131. if (upperBinarySearchLifetime == (lowerBinarySearchLifetime + 1)) {
  132. logger.config("BindingLifetimeTest completed. UDP binding lifetime: " + binarySearchLifetime + ".");
  133. completed = true;
  134. return;
  135. }
  136. lifetime = binarySearchLifetime;
  137. logger.finer("Lifetime update: " + lifetime + ".");
  138. lowerBinarySearchLifetime = binarySearchLifetime;
  139. binarySearchLifetime = ( upperBinarySearchLifetime + lowerBinarySearchLifetime ) / 2;
  140. if (binarySearchLifetime > 0) {
  141. BindingLifetimeTask task = new BindingLifetimeTask();
  142. timer.schedule(task, binarySearchLifetime);
  143. logger.finer("Timer scheduled: " + binarySearchLifetime + ".");
  144. } else {
  145. completed = true;
  146. }
  147. } catch (SocketTimeoutException ste) {
  148. logger.finest("Read operation at query socket timeout.");
  149. if (upperBinarySearchLifetime == (lowerBinarySearchLifetime + 1)) {
  150. logger.config("BindingLifetimeTest completed. UDP binding lifetime: " + binarySearchLifetime + ".");
  151. completed = true;
  152. return;
  153. }
  154. upperBinarySearchLifetime = binarySearchLifetime;
  155. binarySearchLifetime = ( upperBinarySearchLifetime + lowerBinarySearchLifetime ) / 2;
  156. if (binarySearchLifetime > 0) {
  157. if (bindingCommunicationInitialSocket()) {
  158. return;
  159. }
  160. BindingLifetimeTask task = new BindingLifetimeTask();
  161. timer.schedule(task, binarySearchLifetime);
  162. logger.finer("Timer scheduled: " + binarySearchLifetime + ".");
  163. } else {
  164. completed = true;
  165. }
  166. }
  167. }
  168. }
  169. }