1
0

ConverterV15.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #include "memory/Allocator.h"
  16. #include "net/ConverterV15.h"
  17. #include "util/Identity.h"
  18. #include "wire/SwitchHeader.h"
  19. #include "wire/DataHeader.h"
  20. #include "net/SessionManager.h"
  21. #include "wire/ContentType.h"
  22. #include "wire/Headers.h"
  23. #include "util/Checksum.h"
  24. #include "wire/RouteHeader.h"
  25. //#include "util/Hex.h"
  26. struct ConverterV15_pvt
  27. {
  28. struct ConverterV15 pub;
  29. struct SessionManager* sm;
  30. uint8_t myIp6[16];
  31. struct Log* log;
  32. Identity
  33. };
  34. /**
  35. * Incoming packet with a SessionManager header followed by a ContentHeader and then whatever
  36. * content.
  37. */
  38. static Iface_DEFUN incomingFromUpperDistributorIf(struct Message* msg,
  39. struct Iface* upperDistributorIf)
  40. {
  41. struct ConverterV15_pvt* conv =
  42. Identity_containerOf(upperDistributorIf, struct ConverterV15_pvt, pub.upperDistributorIf);
  43. Assert_true(msg->length >= DataHeader_SIZE + RouteHeader_SIZE);
  44. struct RouteHeader* hdr = (struct RouteHeader*) msg->bytes;
  45. struct SessionManager_Session* sess = SessionManager_sessionForIp6(hdr->ip6, conv->sm);
  46. if (hdr->version_be && Endian_bigEndianToHost32(hdr->version_be) < 16) {
  47. // definitely old
  48. } else if (!hdr->version_be && sess && sess->version && sess->version < 16) {
  49. // session thinks it's old
  50. } else {
  51. // nothing is known about a node, fuckit, assume it's new !
  52. return Iface_next(&conv->pub.sessionManagerIf, msg);
  53. }
  54. struct DataHeader* dh = (struct DataHeader*) &hdr[1];
  55. enum ContentType type = DataHeader_getContentType(dh);
  56. if (type > 257) {
  57. Log_debug(conv->log, "DROP unconvertible type [%d]", type);
  58. return NULL;
  59. }
  60. // My fears, come alive,
  61. // in this place where I once died
  62. // demons dreamin',
  63. // Knowing I,
  64. // I just needed to
  65. // _RE_ALIGN_
  66. Message_shift(msg, -(DataHeader_SIZE + RouteHeader_SIZE), NULL);
  67. if (type == ContentType_CJDHT) {
  68. // push a udp header and then an ip header and then checksum the udp
  69. Message_shift(msg, Headers_UDPHeader_SIZE, NULL);
  70. }
  71. if (type != ContentType_IPTUN) {
  72. Message_shift(msg, Headers_IP6Header_SIZE, NULL);
  73. }
  74. Message_shift(msg, RouteHeader_SIZE, NULL);
  75. Bits_memmove(msg->bytes, hdr, RouteHeader_SIZE);
  76. hdr = (struct RouteHeader*) msg->bytes;
  77. if (type == ContentType_IPTUN) {
  78. return Iface_next(&conv->pub.sessionManagerIf, msg);
  79. }
  80. struct Headers_IP6Header* ip6 = (struct Headers_IP6Header*) &hdr[1];
  81. Bits_memset(ip6, 0, Headers_IP6Header_SIZE);
  82. Headers_setIpVersion(ip6);
  83. ip6->hopLimit = 42;
  84. ip6->nextHeader = type;
  85. ip6->payloadLength_be = Endian_hostToBigEndian16(
  86. msg->length - RouteHeader_SIZE - Headers_IP6Header_SIZE);
  87. Bits_memcpyConst(ip6->destinationAddr, hdr->ip6, 16);
  88. Bits_memcpyConst(ip6->sourceAddr, conv->myIp6, 16);
  89. if (type == ContentType_CJDHT) {
  90. struct Headers_UDPHeader* udp = (struct Headers_UDPHeader*) &ip6[1];
  91. ip6->nextHeader = 17;
  92. ip6->hopLimit = 0;
  93. udp->srcPort_be = 0;
  94. udp->destPort_be = 0;
  95. udp->length_be = Endian_hostToBigEndian16(msg->length -
  96. RouteHeader_SIZE -
  97. Headers_IP6Header_SIZE -
  98. Headers_UDPHeader_SIZE);
  99. udp->checksum_be = 0;
  100. udp->checksum_be =
  101. Checksum_udpIp6(ip6->sourceAddr,
  102. (uint8_t*) udp,
  103. msg->length - RouteHeader_SIZE - Headers_IP6Header_SIZE);
  104. //Log_debug(conv->log, "Converted CJDHT->v15");
  105. }
  106. //Log_debug(conv->log, "send [%s]", Hex_print(ip6, 32, msg->alloc));
  107. return Iface_next(&conv->pub.sessionManagerIf, msg);
  108. }
  109. //// --------------- Incoming, convert v15 to v16 --------------- ////
  110. #define tryConvertDHT_OVERHEAD \
  111. (RouteHeader_SIZE + Headers_IP6Header_SIZE + Headers_UDPHeader_SIZE)
  112. static inline bool tryConvertDHT(struct Message* msg)
  113. {
  114. if (msg->length < tryConvertDHT_OVERHEAD) { return false; }
  115. struct RouteHeader* bih = (struct RouteHeader*) msg->bytes;
  116. struct Headers_IP6Header* ip6 = (struct Headers_IP6Header*) &bih[1];
  117. struct Headers_UDPHeader* udp = (struct Headers_UDPHeader*) &ip6[1];
  118. if (udp->srcPort_be || udp->destPort_be) { return false; }
  119. Message_shift(msg, -tryConvertDHT_OVERHEAD, NULL);
  120. struct DataHeader dh = {
  121. .contentType_be = Endian_hostToBigEndian16(ContentType_CJDHT),
  122. .versionAndFlags = DataHeader_CURRENT_VERSION << 4
  123. };
  124. Message_push(msg, &dh, DataHeader_SIZE, NULL);
  125. Message_shift(msg, RouteHeader_SIZE, NULL);
  126. Bits_memmoveConst(msg->bytes, bih, RouteHeader_SIZE);
  127. return true;
  128. }
  129. /**
  130. * Incoming packet with a SessionManager header and under that either an ipv6 or ipv4 header
  131. * depending on whether it's destine for TUN/DHT or IpTunnel.
  132. */
  133. static Iface_DEFUN incomingFromSessionManagerIf(struct Message* msg, struct Iface* sessionManagerIf)
  134. {
  135. struct ConverterV15_pvt* conv =
  136. Identity_containerOf(sessionManagerIf, struct ConverterV15_pvt, pub.sessionManagerIf);
  137. if (msg->length < RouteHeader_SIZE + DataHeader_SIZE) {
  138. Log_debug(conv->log, "DROP runt");
  139. return NULL;
  140. }
  141. struct RouteHeader* bih = (struct RouteHeader*) msg->bytes;
  142. uint8_t* ipPtr = (uint8_t*) &bih[1];
  143. //Log_debug(conv->log, "recv [%s]", Hex_print(ipPtr, 32, msg->alloc));
  144. int ipVer = Headers_getIpVersion(ipPtr);
  145. if (ipVer == DataHeader_CURRENT_VERSION) {
  146. return Iface_next(&conv->pub.upperDistributorIf, msg);
  147. }
  148. if (ipVer == 0) {
  149. if (msg->length < RouteHeader_SIZE + Headers_IP6Header_SIZE) {
  150. Log_debug(conv->log, "DROP runt");
  151. return NULL;
  152. }
  153. struct Headers_IP6Header* ip6 = (struct Headers_IP6Header*) ipPtr;
  154. if (ip6->sourceAddr[0] == 0xfc && ip6->destinationAddr[0] == 0xfc) {
  155. if (tryConvertDHT(msg)) {
  156. return Iface_next(&conv->pub.upperDistributorIf, msg);
  157. }
  158. }
  159. } else if (ipVer == 6) {
  160. if (msg->length < RouteHeader_SIZE + Headers_IP6Header_SIZE) {
  161. Log_debug(conv->log, "DROP runt");
  162. return NULL;
  163. }
  164. struct Headers_IP6Header* ip6 = (struct Headers_IP6Header*) ipPtr;
  165. if (ip6->sourceAddr[0] == 0xfc && ip6->destinationAddr[0] == 0xfc) {
  166. Message_pop(msg, NULL, RouteHeader_SIZE + Headers_IP6Header_SIZE, NULL);
  167. struct DataHeader dh = {
  168. .contentType_be = Endian_hostToBigEndian16(ip6->nextHeader),
  169. .versionAndFlags = DataHeader_CURRENT_VERSION << 4
  170. };
  171. Message_push(msg, &dh, DataHeader_SIZE, NULL);
  172. Message_shift(msg, RouteHeader_SIZE, NULL);
  173. Bits_memmoveConst(msg->bytes, bih, RouteHeader_SIZE);
  174. return Iface_next(&conv->pub.upperDistributorIf, msg);
  175. }
  176. } else if (ipVer != 4) {
  177. Log_debug(conv->log, "DROP unknown packet ip version");
  178. return NULL;
  179. }
  180. Message_shift(msg, DataHeader_SIZE, NULL);
  181. Bits_memmoveConst(msg->bytes, bih, RouteHeader_SIZE);
  182. bih = (struct RouteHeader*) msg->bytes;
  183. struct DataHeader* dh = (struct DataHeader*) &bih[1];
  184. Bits_memset(dh, 0, DataHeader_SIZE);
  185. dh->contentType_be = Endian_hostToBigEndian16(ContentType_IPTUN);
  186. dh->versionAndFlags = DataHeader_CURRENT_VERSION << 4;
  187. return Iface_next(&conv->pub.upperDistributorIf, msg);
  188. }
  189. struct ConverterV15* ConverterV15_new(struct Allocator* alloc,
  190. struct Log* log,
  191. struct SessionManager* sm,
  192. uint8_t myIp6[16])
  193. {
  194. struct ConverterV15_pvt* out = Allocator_calloc(alloc, sizeof(struct ConverterV15_pvt), 1);
  195. out->pub.upperDistributorIf.send = incomingFromUpperDistributorIf;
  196. out->pub.sessionManagerIf.send = incomingFromSessionManagerIf;
  197. out->log = log;
  198. out->sm = sm;
  199. Bits_memcpyConst(out->myIp6, myIp6, 16);
  200. Identity_set(out);
  201. return &out->pub;
  202. }