Unsupported library that attempts to punch holes through NAT
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

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. }