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.

MessageHeader.java 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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.header;
  12. import de.javawi.jstun.attribute.*;
  13. import de.javawi.jstun.util.*;
  14. import java.util.*;
  15. import java.util.logging.*;
  16. public class MessageHeader implements MessageHeaderInterface {
  17. /*
  18. * 0 1 2 3
  19. * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  20. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  21. * | STUN Message Type | Message Length |
  22. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  23. * |
  24. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  25. *
  26. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  27. * Transaction ID
  28. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  29. * |
  30. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  31. */
  32. private static Logger logger = Logger.getLogger("de.javawi.stun.header.MessageHeader");
  33. MessageHeaderType type;
  34. byte[] id = new byte[16];
  35. TreeMap<MessageAttribute.MessageAttributeType, MessageAttribute> ma = new TreeMap<MessageAttribute.MessageAttributeType, MessageAttribute>();
  36. public MessageHeader() {
  37. super();
  38. }
  39. public MessageHeader(MessageHeaderType type) {
  40. super();
  41. setType(type);
  42. }
  43. public void setType(MessageHeaderType type) {
  44. this.type = type;
  45. }
  46. public MessageHeaderType getType() {
  47. return type;
  48. }
  49. public static int typeToInteger(MessageHeaderType type) {
  50. if (type == MessageHeaderType.BindingRequest) return BINDINGREQUEST;
  51. if (type == MessageHeaderType.BindingResponse) return BINDINGRESPONSE;
  52. if (type == MessageHeaderType.BindingErrorResponse) return BINDINGERRORRESPONSE;
  53. if (type == MessageHeaderType.SharedSecretRequest) return SHAREDSECRETREQUEST;
  54. if (type == MessageHeaderType.SharedSecretResponse) return SHAREDSECRETRESPONSE;
  55. if (type == MessageHeaderType.SharedSecretErrorResponse) return SHAREDSECRETERRORRESPONSE;
  56. return -1;
  57. }
  58. public void setTransactionID(byte[] id) {
  59. System.arraycopy(id, 0, this.id, 0, 16);
  60. }
  61. public void generateTransactionID() throws UtilityException {
  62. System.arraycopy(Utility.integerToTwoBytes((int)(Math.random() * 65536)), 0, id, 0, 2);
  63. System.arraycopy(Utility.integerToTwoBytes((int)(Math.random() * 65536)), 0, id, 2, 2);
  64. System.arraycopy(Utility.integerToTwoBytes((int)(Math.random() * 65536)), 0, id, 4, 2);
  65. System.arraycopy(Utility.integerToTwoBytes((int)(Math.random() * 65536)), 0, id, 6, 2);
  66. System.arraycopy(Utility.integerToTwoBytes((int)(Math.random() * 65536)), 0, id, 8, 2);
  67. System.arraycopy(Utility.integerToTwoBytes((int)(Math.random() * 65536)), 0, id, 10, 2);
  68. System.arraycopy(Utility.integerToTwoBytes((int)(Math.random() * 65536)), 0, id, 12, 2);
  69. System.arraycopy(Utility.integerToTwoBytes((int)(Math.random() * 65536)), 0, id, 14, 2);
  70. }
  71. public byte[] getTransactionID() {
  72. byte[] idCopy = new byte[id.length];
  73. System.arraycopy(id, 0, idCopy, 0, id.length);
  74. return idCopy;
  75. }
  76. public boolean equalTransactionID(MessageHeader header) {
  77. byte[] idHeader = header.getTransactionID();
  78. if (idHeader.length != 16) return false;
  79. if ((idHeader[0] == id[0]) && (idHeader[1] == id[1]) && (idHeader[2] == id[2]) && (idHeader[3] == id[3]) &&
  80. (idHeader[4] == id[4]) && (idHeader[5] == id[5]) && (idHeader[6] == id[6]) && (idHeader[7] == id[7]) &&
  81. (idHeader[8] == id[8]) && (idHeader[9] == id[9]) && (idHeader[10] == id[10]) && (idHeader[11] == id[11]) &&
  82. (idHeader[12] == id[12]) && (idHeader[13] == id[13]) && (idHeader[14] == id[14]) && (idHeader[15] == id[15])) {
  83. return true;
  84. } else {
  85. return false;
  86. }
  87. }
  88. public void addMessageAttribute(MessageAttribute attri) {
  89. ma.put(attri.getType(), attri);
  90. }
  91. public MessageAttribute getMessageAttribute(MessageAttribute.MessageAttributeType type) {
  92. return ma.get(type);
  93. }
  94. public byte[] getBytes() throws UtilityException {
  95. int length = 20;
  96. Iterator<MessageAttribute.MessageAttributeType> it = ma.keySet().iterator();
  97. while (it.hasNext()) {
  98. MessageAttribute attri = ma.get(it.next());
  99. length += attri.getLength();
  100. }
  101. // add attribute size + attributes.getSize();
  102. byte[] result = new byte[length];
  103. System.arraycopy(Utility.integerToTwoBytes(typeToInteger(type)), 0, result, 0, 2);
  104. System.arraycopy(Utility.integerToTwoBytes(length-20), 0, result, 2, 2);
  105. System.arraycopy(id, 0, result, 4, 16);
  106. // arraycopy of attributes
  107. int offset = 20;
  108. it = ma.keySet().iterator();
  109. while (it.hasNext()) {
  110. MessageAttribute attri = ma.get(it.next());
  111. System.arraycopy(attri.getBytes(), 0, result, offset, attri.getLength());
  112. offset += attri.getLength();
  113. }
  114. return result;
  115. }
  116. public int getLength() throws UtilityException {
  117. return getBytes().length;
  118. }
  119. public void parseAttributes(byte[] data) throws MessageAttributeParsingException {
  120. try {
  121. byte[] lengthArray = new byte[2];
  122. System.arraycopy(data, 2, lengthArray, 0, 2);
  123. int length = Utility.twoBytesToInteger(lengthArray);
  124. System.arraycopy(data, 4, id, 0, 16);
  125. byte[] cuttedData;
  126. int offset = 20;
  127. while (length > 0) {
  128. cuttedData = new byte[length];
  129. System.arraycopy(data, offset, cuttedData, 0, length);
  130. MessageAttribute ma = MessageAttribute.parseCommonHeader(cuttedData);
  131. addMessageAttribute(ma);
  132. length -= ma.getLength();
  133. offset += ma.getLength();
  134. }
  135. } catch (UtilityException ue) {
  136. throw new MessageAttributeParsingException("Parsing error");
  137. }
  138. }
  139. public static MessageHeader parseHeader(byte[] data) throws MessageHeaderParsingException {
  140. try {
  141. MessageHeader mh = new MessageHeader();
  142. byte[] typeArray = new byte[2];
  143. System.arraycopy(data, 0, typeArray, 0, 2);
  144. int type = Utility.twoBytesToInteger(typeArray);
  145. switch (type) {
  146. case BINDINGREQUEST: mh.setType(MessageHeaderType.BindingRequest); logger.finer("Binding Request received."); break;
  147. case BINDINGRESPONSE: mh.setType(MessageHeaderType.BindingResponse); logger.finer("Binding Response received."); break;
  148. case BINDINGERRORRESPONSE: mh.setType(MessageHeaderType.BindingErrorResponse); logger.finer("Binding Error Response received."); break;
  149. case SHAREDSECRETREQUEST: mh.setType(MessageHeaderType.SharedSecretRequest); logger.finer("Shared Secret Request received."); break;
  150. case SHAREDSECRETRESPONSE: mh.setType(MessageHeaderType.SharedSecretResponse); logger.finer("Shared Secret Response received."); break;
  151. case SHAREDSECRETERRORRESPONSE: mh.setType(MessageHeaderType.SharedSecretErrorResponse); logger.finer("Shared Secret Error Response received.");break;
  152. default: throw new MessageHeaderParsingException("Message type " + type + "is not supported");
  153. }
  154. return mh;
  155. } catch (UtilityException ue) {
  156. throw new MessageHeaderParsingException("Parsing error");
  157. }
  158. }
  159. }