gnunet-service-vpn.c 86 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092
  1. /*
  2. This file is part of GNUnet.
  3. (C) 2010, 2011, 2012 Christian Grothoff
  4. GNUnet is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published
  6. by the Free Software Foundation; either version 3, or (at your
  7. option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNUnet; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  15. Boston, MA 02111-1307, USA.
  16. */
  17. /**
  18. * @file vpn/gnunet-service-vpn.c
  19. * @brief service that opens a virtual interface and allows its clients
  20. * to allocate IPs on the virtual interface and to then redirect
  21. * IP traffic received on those IPs via the GNUnet cadet
  22. * @author Philipp Toelke
  23. * @author Christian Grothoff
  24. *
  25. * TODO:
  26. * - keep multiple peers/cadet channels ready as alternative exits /
  27. * detect & recover from channel-to-exit failure gracefully
  28. */
  29. #include "platform.h"
  30. #include "gnunet_util_lib.h"
  31. #include "gnunet_common.h"
  32. #include "gnunet_protocols.h"
  33. #include "gnunet_applications.h"
  34. #include "gnunet_cadet_service.h"
  35. #include "gnunet_statistics_service.h"
  36. #include "gnunet_constants.h"
  37. #include "gnunet_tun_lib.h"
  38. #include "gnunet_regex_service.h"
  39. #include "vpn.h"
  40. #include "exit.h"
  41. /**
  42. * Maximum number of messages we allow in the queue for cadet.
  43. */
  44. #define MAX_MESSAGE_QUEUE_SIZE 4
  45. /**
  46. * State we keep for each of our channels.
  47. */
  48. struct ChannelState;
  49. /**
  50. * Information we track for each IP address to determine which channel
  51. * to send the traffic over to the destination.
  52. */
  53. struct DestinationEntry;
  54. /**
  55. * List of channels we keep for each destination port for a given
  56. * destination entry.
  57. */
  58. struct DestinationChannel
  59. {
  60. /**
  61. * Kept in a DLL.
  62. */
  63. struct DestinationChannel *next;
  64. /**
  65. * Kept in a DLL.
  66. */
  67. struct DestinationChannel *prev;
  68. /**
  69. * Destination entry list this `struct DestinationChannel` belongs with.
  70. */
  71. struct DestinationEntry *destination;
  72. /**
  73. * Pre-allocated channel for this destination, or NULL for none.
  74. */
  75. struct ChannelState *ts;
  76. /**
  77. * Destination port this channel state is used for.
  78. */
  79. uint16_t destination_port;
  80. };
  81. /**
  82. * Information we track for each IP address to determine which channel
  83. * to send the traffic over to the destination.
  84. */
  85. struct DestinationEntry
  86. {
  87. /**
  88. * Key under which this entry is in the 'destination_map' (only valid
  89. * if 'heap_node != NULL').
  90. */
  91. struct GNUNET_HashCode key;
  92. /**
  93. * Head of DLL of channels associated with this destination.
  94. */
  95. struct DestinationChannel *dt_head;
  96. /**
  97. * Tail of DLL of channels associated with this destination.
  98. */
  99. struct DestinationChannel *dt_tail;
  100. /**
  101. * Entry for this entry in the destination_heap.
  102. */
  103. struct GNUNET_CONTAINER_HeapNode *heap_node;
  104. /**
  105. * #GNUNET_NO if this is a channel to an Internet-exit,
  106. * #GNUNET_YES if this channel is to a service.
  107. */
  108. int is_service;
  109. /**
  110. * Details about the connection (depending on is_service).
  111. */
  112. union
  113. {
  114. struct
  115. {
  116. /**
  117. * The description of the service (only used for service channels).
  118. */
  119. struct GNUNET_HashCode service_descriptor;
  120. /**
  121. * Peer offering the service.
  122. */
  123. struct GNUNET_PeerIdentity target;
  124. } service_destination;
  125. struct
  126. {
  127. /**
  128. * Address family used (AF_INET or AF_INET6).
  129. */
  130. int af;
  131. /**
  132. * IP address of the ultimate destination (only used for exit channels).
  133. */
  134. union
  135. {
  136. /**
  137. * Address if af is AF_INET.
  138. */
  139. struct in_addr v4;
  140. /**
  141. * Address if af is AF_INET6.
  142. */
  143. struct in6_addr v6;
  144. } ip;
  145. } exit_destination;
  146. } details;
  147. };
  148. /**
  149. * A messages we have in queue for a particular channel.
  150. */
  151. struct ChannelMessageQueueEntry
  152. {
  153. /**
  154. * This is a doubly-linked list.
  155. */
  156. struct ChannelMessageQueueEntry *next;
  157. /**
  158. * This is a doubly-linked list.
  159. */
  160. struct ChannelMessageQueueEntry *prev;
  161. /**
  162. * Number of bytes in 'msg'.
  163. */
  164. size_t len;
  165. /**
  166. * Message to transmit, allocated at the end of this struct.
  167. */
  168. const void *msg;
  169. };
  170. /**
  171. * State we keep for each of our channels.
  172. */
  173. struct ChannelState
  174. {
  175. /**
  176. * Information about the channel to use, NULL if no channel
  177. * is available right now.
  178. */
  179. struct GNUNET_CADET_Channel *channel;
  180. /**
  181. * Active query with REGEX to locate exit.
  182. */
  183. struct GNUNET_REGEX_Search *search;
  184. /**
  185. * Active transmission handle, NULL for none.
  186. */
  187. struct GNUNET_CADET_TransmitHandle *th;
  188. /**
  189. * Entry for this entry in the channel_heap, NULL as long as this
  190. * channel state is not fully bound.
  191. */
  192. struct GNUNET_CONTAINER_HeapNode *heap_node;
  193. /**
  194. * Head of list of messages scheduled for transmission.
  195. */
  196. struct ChannelMessageQueueEntry *tmq_head;
  197. /**
  198. * Tail of list of messages scheduled for transmission.
  199. */
  200. struct ChannelMessageQueueEntry *tmq_tail;
  201. /**
  202. * Destination entry that has a pointer to this channel state;
  203. * NULL if this channel state is in the channel map.
  204. */
  205. struct DestinationChannel *destination_container;
  206. /**
  207. * Destination to which this channel leads. Note that
  208. * this struct is NOT in the destination_map (but a
  209. * local copy) and that the 'heap_node' should always
  210. * be NULL.
  211. */
  212. struct DestinationEntry destination;
  213. /**
  214. * Addess family used for this channel on the local TUN interface.
  215. */
  216. int af;
  217. /**
  218. * Length of the doubly linked 'tmq_head/tmq_tail' list.
  219. */
  220. unsigned int tmq_length;
  221. /**
  222. * IPPROTO_TCP or IPPROTO_UDP once bound.
  223. */
  224. uint8_t protocol;
  225. /**
  226. * IP address of the source on our end, initially uninitialized.
  227. */
  228. union
  229. {
  230. /**
  231. * Address if af is AF_INET.
  232. */
  233. struct in_addr v4;
  234. /**
  235. * Address if af is AF_INET6.
  236. */
  237. struct in6_addr v6;
  238. } source_ip;
  239. /**
  240. * Destination IP address used by the source on our end (this is the IP
  241. * that we pick freely within the VPN's channel IP range).
  242. */
  243. union
  244. {
  245. /**
  246. * Address if af is AF_INET.
  247. */
  248. struct in_addr v4;
  249. /**
  250. * Address if af is AF_INET6.
  251. */
  252. struct in6_addr v6;
  253. } destination_ip;
  254. /**
  255. * Source port used by the sender on our end; 0 for uninitialized.
  256. */
  257. uint16_t source_port;
  258. /**
  259. * Destination port used by the sender on our end; 0 for uninitialized.
  260. */
  261. uint16_t destination_port;
  262. };
  263. /**
  264. * Return value from 'main'.
  265. */
  266. static int global_ret;
  267. /**
  268. * Configuration we use.
  269. */
  270. static const struct GNUNET_CONFIGURATION_Handle *cfg;
  271. /**
  272. * Handle to the cadet service.
  273. */
  274. static struct GNUNET_CADET_Handle *cadet_handle;
  275. /**
  276. * Map from IP address to destination information (possibly with a
  277. * CADET channel handle for fast setup).
  278. */
  279. static struct GNUNET_CONTAINER_MultiHashMap *destination_map;
  280. /**
  281. * Min-Heap sorted by activity time to expire old mappings.
  282. */
  283. static struct GNUNET_CONTAINER_Heap *destination_heap;
  284. /**
  285. * Map from source and destination address (IP+port) to connection
  286. * information (mostly with the respective CADET channel handle).
  287. */
  288. static struct GNUNET_CONTAINER_MultiHashMap *channel_map;
  289. /**
  290. * Min-Heap sorted by activity time to expire old mappings; values are
  291. * of type 'struct ChannelState'.
  292. */
  293. static struct GNUNET_CONTAINER_Heap *channel_heap;
  294. /**
  295. * Statistics.
  296. */
  297. static struct GNUNET_STATISTICS_Handle *stats;
  298. /**
  299. * The handle to the VPN helper process "gnunet-helper-vpn".
  300. */
  301. static struct GNUNET_HELPER_Handle *helper_handle;
  302. /**
  303. * Arguments to the vpn helper.
  304. */
  305. static char *vpn_argv[7];
  306. /**
  307. * Length of the prefix of the VPN's IPv6 network.
  308. */
  309. static unsigned long long ipv6prefix;
  310. /**
  311. * Notification context for sending replies to clients.
  312. */
  313. static struct GNUNET_SERVER_NotificationContext *nc;
  314. /**
  315. * If there are more than this number of address-mappings, old ones
  316. * will be removed
  317. */
  318. static unsigned long long max_destination_mappings;
  319. /**
  320. * If there are more than this number of open channels, old ones
  321. * will be removed
  322. */
  323. static unsigned long long max_channel_mappings;
  324. /**
  325. * Compute the key under which we would store an entry in the
  326. * destination_map for the given IP address.
  327. *
  328. * @param af address family (AF_INET or AF_INET6)
  329. * @param address IP address, struct in_addr or struct in6_addr
  330. * @param key where to store the key
  331. */
  332. static void
  333. get_destination_key_from_ip (int af,
  334. const void *address,
  335. struct GNUNET_HashCode *key)
  336. {
  337. switch (af)
  338. {
  339. case AF_INET:
  340. GNUNET_CRYPTO_hash (address,
  341. sizeof (struct in_addr),
  342. key);
  343. break;
  344. case AF_INET6:
  345. GNUNET_CRYPTO_hash (address,
  346. sizeof (struct in6_addr),
  347. key);
  348. break;
  349. default:
  350. GNUNET_assert (0);
  351. break;
  352. }
  353. }
  354. /**
  355. * Compute the key under which we would store an entry in the
  356. * channel_map for the given socket address pair.
  357. *
  358. * @param af address family (AF_INET or AF_INET6)
  359. * @param protocol IPPROTO_TCP or IPPROTO_UDP
  360. * @param source_ip sender's source IP, struct in_addr or struct in6_addr
  361. * @param source_port sender's source port
  362. * @param destination_ip sender's destination IP, struct in_addr or struct in6_addr
  363. * @param destination_port sender's destination port
  364. * @param key where to store the key
  365. */
  366. static void
  367. get_channel_key_from_ips (int af,
  368. uint8_t protocol,
  369. const void *source_ip,
  370. uint16_t source_port,
  371. const void *destination_ip,
  372. uint16_t destination_port,
  373. struct GNUNET_HashCode *key)
  374. {
  375. char *off;
  376. memset (key, 0, sizeof (struct GNUNET_HashCode));
  377. /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
  378. so we put the ports in there (and hope for few collisions) */
  379. off = (char*) key;
  380. memcpy (off, &source_port, sizeof (uint16_t));
  381. off += sizeof (uint16_t);
  382. memcpy (off, &destination_port, sizeof (uint16_t));
  383. off += sizeof (uint16_t);
  384. switch (af)
  385. {
  386. case AF_INET:
  387. memcpy (off, source_ip, sizeof (struct in_addr));
  388. off += sizeof (struct in_addr);
  389. memcpy (off, destination_ip, sizeof (struct in_addr));
  390. off += sizeof (struct in_addr);
  391. break;
  392. case AF_INET6:
  393. memcpy (off, source_ip, sizeof (struct in6_addr));
  394. off += sizeof (struct in6_addr);
  395. memcpy (off, destination_ip, sizeof (struct in6_addr));
  396. off += sizeof (struct in6_addr);
  397. break;
  398. default:
  399. GNUNET_assert (0);
  400. break;
  401. }
  402. memcpy (off, &protocol, sizeof (uint8_t));
  403. /* off += sizeof (uint8_t); */
  404. }
  405. /**
  406. * Notify the client about the result of its request.
  407. *
  408. * @param client client to notify
  409. * @param request_id original request ID to include in response
  410. * @param result_af resulting address family
  411. * @param addr resulting IP address
  412. */
  413. static void
  414. send_client_reply (struct GNUNET_SERVER_Client *client,
  415. uint64_t request_id,
  416. int result_af,
  417. const void *addr)
  418. {
  419. char buf[sizeof (struct RedirectToIpResponseMessage) + sizeof (struct in6_addr)] GNUNET_ALIGN;
  420. struct RedirectToIpResponseMessage *res;
  421. size_t rlen;
  422. switch (result_af)
  423. {
  424. case AF_INET:
  425. rlen = sizeof (struct in_addr);
  426. break;
  427. case AF_INET6:
  428. rlen = sizeof (struct in6_addr);
  429. break;
  430. case AF_UNSPEC:
  431. rlen = 0;
  432. break;
  433. default:
  434. GNUNET_assert (0);
  435. return;
  436. }
  437. res = (struct RedirectToIpResponseMessage *) buf;
  438. res->header.size = htons (sizeof (struct RedirectToIpResponseMessage) + rlen);
  439. res->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP);
  440. res->result_af = htonl (result_af);
  441. res->request_id = request_id;
  442. memcpy (&res[1], addr, rlen);
  443. GNUNET_SERVER_notification_context_add (nc, client);
  444. GNUNET_SERVER_notification_context_unicast (nc,
  445. client,
  446. &res->header,
  447. GNUNET_NO);
  448. }
  449. /**
  450. * Free resources associated with a channel state.
  451. *
  452. * @param ts state to free
  453. */
  454. static void
  455. free_channel_state (struct ChannelState *ts)
  456. {
  457. struct GNUNET_HashCode key;
  458. struct ChannelMessageQueueEntry *tnq;
  459. struct GNUNET_CADET_Channel *channel;
  460. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  461. "Cleaning up channel state\n");
  462. GNUNET_STATISTICS_update (stats,
  463. gettext_noop ("# Active channels"),
  464. -1, GNUNET_NO);
  465. while (NULL != (tnq = ts->tmq_head))
  466. {
  467. GNUNET_CONTAINER_DLL_remove (ts->tmq_head,
  468. ts->tmq_tail,
  469. tnq);
  470. ts->tmq_length--;
  471. GNUNET_free (tnq);
  472. }
  473. GNUNET_assert (0 == ts->tmq_length);
  474. if (NULL != ts->th)
  475. {
  476. GNUNET_CADET_notify_transmit_ready_cancel (ts->th);
  477. ts->th = NULL;
  478. }
  479. GNUNET_assert (NULL == ts->destination.heap_node);
  480. if (NULL != (channel = ts->channel))
  481. {
  482. ts->channel = NULL;
  483. GNUNET_CADET_channel_destroy (channel);
  484. }
  485. if (NULL != ts->search)
  486. {
  487. GNUNET_REGEX_search_cancel (ts->search);
  488. ts->search = NULL;
  489. }
  490. if (NULL != ts->heap_node)
  491. {
  492. GNUNET_CONTAINER_heap_remove_node (ts->heap_node);
  493. ts->heap_node = NULL;
  494. get_channel_key_from_ips (ts->af,
  495. ts->protocol,
  496. &ts->source_ip,
  497. ts->source_port,
  498. &ts->destination_ip,
  499. ts->destination_port,
  500. &key);
  501. GNUNET_assert (GNUNET_YES ==
  502. GNUNET_CONTAINER_multihashmap_remove (channel_map,
  503. &key,
  504. ts));
  505. }
  506. if (NULL != ts->destination_container)
  507. {
  508. GNUNET_assert (ts == ts->destination_container->ts);
  509. ts->destination_container->ts = NULL;
  510. ts->destination_container = NULL;
  511. }
  512. GNUNET_free (ts);
  513. }
  514. /**
  515. * Send a message from the message queue via cadet.
  516. *
  517. * @param cls the `struct ChannelState` with the message queue
  518. * @param size number of bytes available in @a buf
  519. * @param buf where to copy the message
  520. * @return number of bytes copied to @a buf
  521. */
  522. static size_t
  523. send_to_peer_notify_callback (void *cls, size_t size, void *buf)
  524. {
  525. struct ChannelState *ts = cls;
  526. struct ChannelMessageQueueEntry *tnq;
  527. size_t ret;
  528. ts->th = NULL;
  529. if (NULL == buf)
  530. return 0;
  531. tnq = ts->tmq_head;
  532. GNUNET_assert (NULL != tnq);
  533. GNUNET_assert (size >= tnq->len);
  534. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  535. "Sending %u bytes via cadet channel\n",
  536. tnq->len);
  537. GNUNET_CONTAINER_DLL_remove (ts->tmq_head,
  538. ts->tmq_tail,
  539. tnq);
  540. ts->tmq_length--;
  541. memcpy (buf, tnq->msg, tnq->len);
  542. ret = tnq->len;
  543. GNUNET_free (tnq);
  544. if (NULL != (tnq = ts->tmq_head))
  545. ts->th = GNUNET_CADET_notify_transmit_ready (ts->channel,
  546. GNUNET_NO /* cork */,
  547. GNUNET_TIME_UNIT_FOREVER_REL,
  548. tnq->len,
  549. &send_to_peer_notify_callback,
  550. ts);
  551. GNUNET_STATISTICS_update (stats,
  552. gettext_noop ("# Bytes given to cadet for transmission"),
  553. ret, GNUNET_NO);
  554. return ret;
  555. }
  556. /**
  557. * Add the given message to the given channel and trigger the
  558. * transmission process.
  559. *
  560. * @param tnq message to queue
  561. * @param ts channel to queue the message for
  562. */
  563. static void
  564. send_to_channel (struct ChannelMessageQueueEntry *tnq,
  565. struct ChannelState *ts)
  566. {
  567. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  568. "Queueing %u bytes for transmission via cadet channel\n",
  569. tnq->len);
  570. GNUNET_assert (NULL != ts->channel);
  571. GNUNET_CONTAINER_DLL_insert_tail (ts->tmq_head,
  572. ts->tmq_tail,
  573. tnq);
  574. ts->tmq_length++;
  575. if (ts->tmq_length > MAX_MESSAGE_QUEUE_SIZE)
  576. {
  577. struct ChannelMessageQueueEntry *dq;
  578. dq = ts->tmq_head;
  579. GNUNET_assert (dq != tnq);
  580. GNUNET_CONTAINER_DLL_remove (ts->tmq_head,
  581. ts->tmq_tail,
  582. dq);
  583. ts->tmq_length--;
  584. GNUNET_CADET_notify_transmit_ready_cancel (ts->th);
  585. ts->th = NULL;
  586. GNUNET_STATISTICS_update (stats,
  587. gettext_noop ("# Bytes dropped in cadet queue (overflow)"),
  588. dq->len,
  589. GNUNET_NO);
  590. GNUNET_free (dq);
  591. }
  592. if (NULL == ts->th)
  593. ts->th = GNUNET_CADET_notify_transmit_ready (ts->channel,
  594. GNUNET_NO /* cork */,
  595. GNUNET_TIME_UNIT_FOREVER_REL,
  596. tnq->len,
  597. &send_to_peer_notify_callback,
  598. ts);
  599. }
  600. /**
  601. * Regex has found a potential exit peer for us; consider using it.
  602. *
  603. * @param cls the 'struct ChannelState'
  604. * @param id Peer providing a regex that matches the string.
  605. * @param get_path Path of the get request.
  606. * @param get_path_length Lenght of @a get_path.
  607. * @param put_path Path of the put request.
  608. * @param put_path_length Length of the @a put_path.
  609. */
  610. static void
  611. handle_regex_result (void *cls,
  612. const struct GNUNET_PeerIdentity *id,
  613. const struct GNUNET_PeerIdentity *get_path,
  614. unsigned int get_path_length,
  615. const struct GNUNET_PeerIdentity *put_path,
  616. unsigned int put_path_length)
  617. {
  618. struct ChannelState *ts = cls;
  619. unsigned int apptype;
  620. GNUNET_REGEX_search_cancel (ts->search);
  621. ts->search = NULL;
  622. switch (ts->af)
  623. {
  624. case AF_INET:
  625. apptype = GNUNET_APPLICATION_TYPE_IPV4_GATEWAY;
  626. break;
  627. case AF_INET6:
  628. apptype = GNUNET_APPLICATION_TYPE_IPV6_GATEWAY;
  629. break;
  630. default:
  631. GNUNET_break (0);
  632. return;
  633. }
  634. ts->channel = GNUNET_CADET_channel_create (cadet_handle,
  635. ts,
  636. id,
  637. apptype,
  638. GNUNET_CADET_OPTION_DEFAULT);
  639. }
  640. /**
  641. * Initialize the given destination entry's cadet channel.
  642. *
  643. * @param dt destination channel for which we need to setup a channel
  644. * @param client_af address family of the address returned to the client
  645. * @return channel state of the channel that was created
  646. */
  647. static struct ChannelState *
  648. create_channel_to_destination (struct DestinationChannel *dt,
  649. int client_af)
  650. {
  651. struct ChannelState *ts;
  652. unsigned int apptype;
  653. GNUNET_STATISTICS_update (stats,
  654. gettext_noop ("# Cadet channels created"),
  655. 1, GNUNET_NO);
  656. GNUNET_assert (NULL == dt->ts);
  657. switch (client_af)
  658. {
  659. case AF_INET:
  660. apptype = GNUNET_APPLICATION_TYPE_IPV4_GATEWAY;
  661. break;
  662. case AF_INET6:
  663. apptype = GNUNET_APPLICATION_TYPE_IPV6_GATEWAY;
  664. break;
  665. default:
  666. GNUNET_break (0);
  667. return NULL;
  668. }
  669. ts = GNUNET_new (struct ChannelState);
  670. ts->af = client_af;
  671. ts->destination = *dt->destination;
  672. ts->destination.heap_node = NULL; /* copy is NOT in destination heap */
  673. dt->ts = ts;
  674. ts->destination_container = dt; /* we are referenced from dt */
  675. if (dt->destination->is_service)
  676. {
  677. ts->channel = GNUNET_CADET_channel_create (cadet_handle,
  678. ts,
  679. &dt->destination->details.service_destination.target,
  680. apptype,
  681. GNUNET_CADET_OPTION_DEFAULT);
  682. if (NULL == ts->channel)
  683. {
  684. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  685. _("Failed to setup cadet channel!\n"));
  686. GNUNET_free (ts);
  687. return NULL;
  688. }
  689. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  690. "Creating channel to peer %s offering service %s\n",
  691. GNUNET_i2s (&dt->destination->details.service_destination.target),
  692. GNUNET_h2s (&dt->destination->details.service_destination.service_descriptor));
  693. }
  694. else
  695. {
  696. char *policy;
  697. switch (dt->destination->details.exit_destination.af)
  698. {
  699. case AF_INET:
  700. {
  701. char address[GNUNET_TUN_IPV4_REGEXLEN];
  702. GNUNET_TUN_ipv4toregexsearch (&dt->destination->details.exit_destination.ip.v4,
  703. dt->destination_port,
  704. address);
  705. GNUNET_asprintf (&policy, "%s%s",
  706. GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX,
  707. address);
  708. break;
  709. }
  710. case AF_INET6:
  711. {
  712. char address[GNUNET_TUN_IPV6_REGEXLEN];
  713. GNUNET_TUN_ipv6toregexsearch (&dt->destination->details.exit_destination.ip.v6,
  714. dt->destination_port,
  715. address);
  716. GNUNET_asprintf (&policy, "%s%s",
  717. GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX,
  718. address);
  719. break;
  720. }
  721. default:
  722. GNUNET_assert (0);
  723. break;
  724. }
  725. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  726. "Requesting connect by string: %s\n",
  727. policy);
  728. ts->search = GNUNET_REGEX_search (cfg,
  729. policy,
  730. &handle_regex_result,
  731. ts);
  732. GNUNET_free (policy);
  733. }
  734. return ts;
  735. }
  736. /**
  737. * We have too many active channels. Clean up the oldest channel.
  738. *
  739. * @param except channel that must NOT be cleaned up, even if it is the oldest
  740. */
  741. static void
  742. expire_channel (struct ChannelState *except)
  743. {
  744. struct ChannelState *ts;
  745. ts = GNUNET_CONTAINER_heap_peek (channel_heap);
  746. GNUNET_assert (NULL != ts);
  747. if (except == ts)
  748. return; /* can't do this */
  749. free_channel_state (ts);
  750. }
  751. /**
  752. * Route a packet via cadet to the given destination.
  753. *
  754. * @param destination description of the destination
  755. * @param af address family on this end (AF_INET or AF_INET6)
  756. * @param protocol IPPROTO_TCP or IPPROTO_UDP or IPPROTO_ICMP or IPPROTO_ICMPV6
  757. * @param source_ip source IP used by the sender (struct in_addr or struct in6_addr)
  758. * @param destination_ip destination IP used by the sender (struct in_addr or struct in6_addr)
  759. * @param payload payload of the packet after the IP header
  760. * @param payload_length number of bytes in @a payload
  761. */
  762. static void
  763. route_packet (struct DestinationEntry *destination,
  764. int af,
  765. uint8_t protocol,
  766. const void *source_ip,
  767. const void *destination_ip,
  768. const void *payload,
  769. size_t payload_length)
  770. {
  771. struct GNUNET_HashCode key;
  772. struct ChannelState *ts;
  773. struct ChannelMessageQueueEntry *tnq;
  774. size_t alen;
  775. size_t mlen;
  776. int is_new;
  777. const struct GNUNET_TUN_UdpHeader *udp;
  778. const struct GNUNET_TUN_TcpHeader *tcp;
  779. const struct GNUNET_TUN_IcmpHeader *icmp;
  780. struct DestinationChannel *dt;
  781. uint16_t source_port;
  782. uint16_t destination_port;
  783. switch (protocol)
  784. {
  785. case IPPROTO_UDP:
  786. {
  787. if (payload_length < sizeof (struct GNUNET_TUN_UdpHeader))
  788. {
  789. /* blame kernel? */
  790. GNUNET_break (0);
  791. return;
  792. }
  793. tcp = NULL; /* make compiler happy */
  794. icmp = NULL; /* make compiler happy */
  795. udp = payload;
  796. if (udp->len < sizeof (struct GNUNET_TUN_UdpHeader))
  797. {
  798. GNUNET_break_op (0);
  799. return;
  800. }
  801. source_port = ntohs (udp->source_port);
  802. destination_port = ntohs (udp->destination_port);
  803. get_channel_key_from_ips (af,
  804. IPPROTO_UDP,
  805. source_ip,
  806. source_port,
  807. destination_ip,
  808. destination_port,
  809. &key);
  810. }
  811. break;
  812. case IPPROTO_TCP:
  813. {
  814. if (payload_length < sizeof (struct GNUNET_TUN_TcpHeader))
  815. {
  816. /* blame kernel? */
  817. GNUNET_break (0);
  818. return;
  819. }
  820. udp = NULL; /* make compiler happy */
  821. icmp = NULL; /* make compiler happy */
  822. tcp = payload;
  823. if (tcp->off * 4 < sizeof (struct GNUNET_TUN_TcpHeader))
  824. {
  825. GNUNET_break_op (0);
  826. return;
  827. }
  828. source_port = ntohs (tcp->source_port);
  829. destination_port = ntohs (tcp->destination_port);
  830. get_channel_key_from_ips (af,
  831. IPPROTO_TCP,
  832. source_ip,
  833. source_port,
  834. destination_ip,
  835. destination_port,
  836. &key);
  837. }
  838. break;
  839. case IPPROTO_ICMP:
  840. case IPPROTO_ICMPV6:
  841. {
  842. if ( (AF_INET == af) ^ (protocol == IPPROTO_ICMP) )
  843. {
  844. GNUNET_break (0);
  845. return;
  846. }
  847. if (payload_length < sizeof (struct GNUNET_TUN_IcmpHeader))
  848. {
  849. /* blame kernel? */
  850. GNUNET_break (0);
  851. return;
  852. }
  853. tcp = NULL; /* make compiler happy */
  854. udp = NULL; /* make compiler happy */
  855. icmp = payload;
  856. source_port = 0;
  857. destination_port = 0;
  858. get_channel_key_from_ips (af,
  859. protocol,
  860. source_ip,
  861. 0,
  862. destination_ip,
  863. 0,
  864. &key);
  865. }
  866. break;
  867. default:
  868. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  869. _("Protocol %u not supported, dropping\n"),
  870. (unsigned int) protocol);
  871. return;
  872. }
  873. alen = 0;
  874. if (! destination->is_service)
  875. {
  876. switch (destination->details.exit_destination.af)
  877. {
  878. case AF_INET:
  879. alen = sizeof (struct in_addr);
  880. break;
  881. case AF_INET6:
  882. alen = sizeof (struct in6_addr);
  883. break;
  884. default:
  885. GNUNET_assert (0);
  886. }
  887. {
  888. char sbuf[INET6_ADDRSTRLEN];
  889. char dbuf[INET6_ADDRSTRLEN];
  890. char xbuf[INET6_ADDRSTRLEN];
  891. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  892. "Routing %s packet from %s:%u -> %s:%u to destination %s:%u\n",
  893. (protocol == IPPROTO_TCP) ? "TCP" : "UDP",
  894. inet_ntop (af, source_ip, sbuf, sizeof (sbuf)),
  895. source_port,
  896. inet_ntop (af, destination_ip, dbuf, sizeof (dbuf)),
  897. destination_port,
  898. inet_ntop (destination->details.exit_destination.af,
  899. &destination->details.exit_destination.ip,
  900. xbuf, sizeof (xbuf)),
  901. destination_port);
  902. }
  903. for (dt = destination->dt_head; NULL != dt; dt = dt->next)
  904. if (dt->destination_port == destination_port)
  905. break;
  906. }
  907. else
  908. {
  909. {
  910. char sbuf[INET6_ADDRSTRLEN];
  911. char dbuf[INET6_ADDRSTRLEN];
  912. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  913. "Routing %s packet from %s:%u -> %s:%u to service %s at peer %s\n",
  914. (protocol == IPPROTO_TCP) ? "TCP" : "UDP",
  915. inet_ntop (af, source_ip, sbuf, sizeof (sbuf)),
  916. source_port,
  917. inet_ntop (af, destination_ip, dbuf, sizeof (dbuf)),
  918. destination_port,
  919. GNUNET_h2s (&destination->details.service_destination.service_descriptor),
  920. GNUNET_i2s (&destination->details.service_destination.target));
  921. }
  922. dt = destination->dt_head;
  923. }
  924. if (NULL == dt)
  925. {
  926. dt = GNUNET_new (struct DestinationChannel);
  927. dt->destination = destination;
  928. GNUNET_CONTAINER_DLL_insert (destination->dt_head,
  929. destination->dt_tail,
  930. dt);
  931. dt->destination_port = destination_port;
  932. }
  933. /* see if we have an existing channel for this destination */
  934. ts = GNUNET_CONTAINER_multihashmap_get (channel_map,
  935. &key);
  936. if (NULL == ts)
  937. {
  938. /* need to either use the existing channel from the destination (if still
  939. available) or create a fresh one */
  940. is_new = GNUNET_YES;
  941. if (NULL == dt->ts)
  942. ts = create_channel_to_destination (dt, af);
  943. else
  944. ts = dt->ts;
  945. if (NULL == ts)
  946. return;
  947. dt->ts = NULL;
  948. ts->destination_container = NULL; /* no longer 'contained' */
  949. /* now bind existing "unbound" channel to our IP/port tuple */
  950. ts->protocol = protocol;
  951. ts->af = af;
  952. if (AF_INET == af)
  953. {
  954. ts->source_ip.v4 = * (const struct in_addr *) source_ip;
  955. ts->destination_ip.v4 = * (const struct in_addr *) destination_ip;
  956. }
  957. else
  958. {
  959. ts->source_ip.v6 = * (const struct in6_addr *) source_ip;
  960. ts->destination_ip.v6 = * (const struct in6_addr *) destination_ip;
  961. }
  962. ts->source_port = source_port;
  963. ts->destination_port = destination_port;
  964. ts->heap_node = GNUNET_CONTAINER_heap_insert (channel_heap,
  965. ts,
  966. GNUNET_TIME_absolute_get ().abs_value_us);
  967. GNUNET_assert (GNUNET_YES ==
  968. GNUNET_CONTAINER_multihashmap_put (channel_map,
  969. &key,
  970. ts,
  971. GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
  972. GNUNET_STATISTICS_update (stats,
  973. gettext_noop ("# Active channels"),
  974. 1, GNUNET_NO);
  975. while (GNUNET_CONTAINER_multihashmap_size (channel_map) > max_channel_mappings)
  976. expire_channel (ts);
  977. }
  978. else
  979. {
  980. is_new = GNUNET_NO;
  981. GNUNET_CONTAINER_heap_update_cost (channel_heap,
  982. ts->heap_node,
  983. GNUNET_TIME_absolute_get ().abs_value_us);
  984. }
  985. GNUNET_assert (NULL != ts->channel);
  986. /* send via channel */
  987. switch (protocol)
  988. {
  989. case IPPROTO_UDP:
  990. if (destination->is_service)
  991. {
  992. struct GNUNET_EXIT_UdpServiceMessage *usm;
  993. mlen = sizeof (struct GNUNET_EXIT_UdpServiceMessage) +
  994. payload_length - sizeof (struct GNUNET_TUN_UdpHeader);
  995. if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
  996. {
  997. GNUNET_break (0);
  998. return;
  999. }
  1000. tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen);
  1001. tnq->len = mlen;
  1002. tnq->msg = &tnq[1];
  1003. usm = (struct GNUNET_EXIT_UdpServiceMessage *) &tnq[1];
  1004. usm->header.size = htons ((uint16_t) mlen);
  1005. usm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE);
  1006. /* if the source port is below 32000, we assume it has a special
  1007. meaning; if not, we pick a random port (this is a heuristic) */
  1008. usm->source_port = (ntohs (udp->source_port) < 32000) ? udp->source_port : 0;
  1009. usm->destination_port = udp->destination_port;
  1010. usm->service_descriptor = destination->details.service_destination.service_descriptor;
  1011. memcpy (&usm[1],
  1012. &udp[1],
  1013. payload_length - sizeof (struct GNUNET_TUN_UdpHeader));
  1014. }
  1015. else
  1016. {
  1017. struct GNUNET_EXIT_UdpInternetMessage *uim;
  1018. struct in_addr *ip4dst;
  1019. struct in6_addr *ip6dst;
  1020. void *payload;
  1021. mlen = sizeof (struct GNUNET_EXIT_UdpInternetMessage) +
  1022. alen + payload_length - sizeof (struct GNUNET_TUN_UdpHeader);
  1023. if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
  1024. {
  1025. GNUNET_break (0);
  1026. return;
  1027. }
  1028. tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen);
  1029. tnq->len = mlen;
  1030. tnq->msg = &tnq[1];
  1031. uim = (struct GNUNET_EXIT_UdpInternetMessage *) &tnq[1];
  1032. uim->header.size = htons ((uint16_t) mlen);
  1033. uim->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET);
  1034. uim->af = htonl (destination->details.exit_destination.af);
  1035. uim->source_port = (ntohs (udp->source_port) < 32000) ? udp->source_port : 0;
  1036. uim->destination_port = udp->destination_port;
  1037. switch (destination->details.exit_destination.af)
  1038. {
  1039. case AF_INET:
  1040. ip4dst = (struct in_addr *) &uim[1];
  1041. *ip4dst = destination->details.exit_destination.ip.v4;
  1042. payload = &ip4dst[1];
  1043. break;
  1044. case AF_INET6:
  1045. ip6dst = (struct in6_addr *) &uim[1];
  1046. *ip6dst = destination->details.exit_destination.ip.v6;
  1047. payload = &ip6dst[1];
  1048. break;
  1049. default:
  1050. GNUNET_assert (0);
  1051. }
  1052. memcpy (payload,
  1053. &udp[1],
  1054. payload_length - sizeof (struct GNUNET_TUN_UdpHeader));
  1055. }
  1056. break;
  1057. case IPPROTO_TCP:
  1058. if (is_new)
  1059. {
  1060. if (destination->is_service)
  1061. {
  1062. struct GNUNET_EXIT_TcpServiceStartMessage *tsm;
  1063. mlen = sizeof (struct GNUNET_EXIT_TcpServiceStartMessage) +
  1064. payload_length - sizeof (struct GNUNET_TUN_TcpHeader);
  1065. if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
  1066. {
  1067. GNUNET_break (0);
  1068. return;
  1069. }
  1070. tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen);
  1071. tnq->len = mlen;
  1072. tnq->msg = &tnq[1];
  1073. tsm = (struct GNUNET_EXIT_TcpServiceStartMessage *) &tnq[1];
  1074. tsm->header.size = htons ((uint16_t) mlen);
  1075. tsm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START);
  1076. tsm->reserved = htonl (0);
  1077. tsm->service_descriptor = destination->details.service_destination.service_descriptor;
  1078. tsm->tcp_header = *tcp;
  1079. memcpy (&tsm[1],
  1080. &tcp[1],
  1081. payload_length - sizeof (struct GNUNET_TUN_TcpHeader));
  1082. }
  1083. else
  1084. {
  1085. struct GNUNET_EXIT_TcpInternetStartMessage *tim;
  1086. struct in_addr *ip4dst;
  1087. struct in6_addr *ip6dst;
  1088. void *payload;
  1089. mlen = sizeof (struct GNUNET_EXIT_TcpInternetStartMessage) +
  1090. alen + payload_length - sizeof (struct GNUNET_TUN_TcpHeader);
  1091. if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
  1092. {
  1093. GNUNET_break (0);
  1094. return;
  1095. }
  1096. tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen);
  1097. tnq->len = mlen;
  1098. tnq->msg = &tnq[1];
  1099. tim = (struct GNUNET_EXIT_TcpInternetStartMessage *) &tnq[1];
  1100. tim->header.size = htons ((uint16_t) mlen);
  1101. tim->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START);
  1102. tim->af = htonl (destination->details.exit_destination.af);
  1103. tim->tcp_header = *tcp;
  1104. switch (destination->details.exit_destination.af)
  1105. {
  1106. case AF_INET:
  1107. ip4dst = (struct in_addr *) &tim[1];
  1108. *ip4dst = destination->details.exit_destination.ip.v4;
  1109. payload = &ip4dst[1];
  1110. break;
  1111. case AF_INET6:
  1112. ip6dst = (struct in6_addr *) &tim[1];
  1113. *ip6dst = destination->details.exit_destination.ip.v6;
  1114. payload = &ip6dst[1];
  1115. break;
  1116. default:
  1117. GNUNET_assert (0);
  1118. }
  1119. memcpy (payload,
  1120. &tcp[1],
  1121. payload_length - sizeof (struct GNUNET_TUN_TcpHeader));
  1122. }
  1123. }
  1124. else
  1125. {
  1126. struct GNUNET_EXIT_TcpDataMessage *tdm;
  1127. mlen = sizeof (struct GNUNET_EXIT_TcpDataMessage) +
  1128. payload_length - sizeof (struct GNUNET_TUN_TcpHeader);
  1129. if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
  1130. {
  1131. GNUNET_break (0);
  1132. return;
  1133. }
  1134. tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen);
  1135. tnq->len = mlen;
  1136. tnq->msg = &tnq[1];
  1137. tdm = (struct GNUNET_EXIT_TcpDataMessage *) &tnq[1];
  1138. tdm->header.size = htons ((uint16_t) mlen);
  1139. tdm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT);
  1140. tdm->reserved = htonl (0);
  1141. tdm->tcp_header = *tcp;
  1142. memcpy (&tdm[1],
  1143. &tcp[1],
  1144. payload_length - sizeof (struct GNUNET_TUN_TcpHeader));
  1145. }
  1146. break;
  1147. case IPPROTO_ICMP:
  1148. case IPPROTO_ICMPV6:
  1149. if (destination->is_service)
  1150. {
  1151. struct GNUNET_EXIT_IcmpServiceMessage *ism;
  1152. mlen = sizeof (struct GNUNET_EXIT_IcmpServiceMessage) +
  1153. payload_length - sizeof (struct GNUNET_TUN_IcmpHeader);
  1154. if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
  1155. {
  1156. GNUNET_break (0);
  1157. return;
  1158. }
  1159. tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen);
  1160. tnq->msg = &tnq[1];
  1161. ism = (struct GNUNET_EXIT_IcmpServiceMessage *) &tnq[1];
  1162. ism->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE);
  1163. ism->af = htonl (af); /* need to tell destination ICMP protocol family! */
  1164. ism->service_descriptor = destination->details.service_destination.service_descriptor;
  1165. ism->icmp_header = *icmp;
  1166. /* ICMP protocol translation will be done by the receiver (as we don't know
  1167. the target AF); however, we still need to possibly discard the payload
  1168. depending on the ICMP type */
  1169. switch (af)
  1170. {
  1171. case AF_INET:
  1172. switch (icmp->type)
  1173. {
  1174. case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
  1175. case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
  1176. break;
  1177. case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
  1178. case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
  1179. case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
  1180. /* throw away ICMP payload, won't be useful for the other side anyway */
  1181. payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
  1182. break;
  1183. default:
  1184. GNUNET_STATISTICS_update (stats,
  1185. gettext_noop ("# ICMPv4 packets dropped (not allowed)"),
  1186. 1, GNUNET_NO);
  1187. return;
  1188. }
  1189. /* end of AF_INET */
  1190. break;
  1191. case AF_INET6:
  1192. switch (icmp->type)
  1193. {
  1194. case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
  1195. case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
  1196. case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
  1197. case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
  1198. /* throw away ICMP payload, won't be useful for the other side anyway */
  1199. payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
  1200. break;
  1201. case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
  1202. case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY:
  1203. break;
  1204. default:
  1205. GNUNET_STATISTICS_update (stats,
  1206. gettext_noop ("# ICMPv6 packets dropped (not allowed)"),
  1207. 1, GNUNET_NO);
  1208. return;
  1209. }
  1210. /* end of AF_INET6 */
  1211. break;
  1212. default:
  1213. GNUNET_assert (0);
  1214. break;
  1215. }
  1216. /* update length calculations, as payload_length may have changed */
  1217. mlen = sizeof (struct GNUNET_EXIT_IcmpServiceMessage) +
  1218. alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader);
  1219. tnq->len = mlen;
  1220. ism->header.size = htons ((uint16_t) mlen);
  1221. /* finally, copy payload (if there is any left...) */
  1222. memcpy (&ism[1],
  1223. &icmp[1],
  1224. payload_length - sizeof (struct GNUNET_TUN_IcmpHeader));
  1225. }
  1226. else
  1227. {
  1228. struct GNUNET_EXIT_IcmpInternetMessage *iim;
  1229. struct in_addr *ip4dst;
  1230. struct in6_addr *ip6dst;
  1231. void *payload;
  1232. mlen = sizeof (struct GNUNET_EXIT_IcmpInternetMessage) +
  1233. alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader);
  1234. if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
  1235. {
  1236. GNUNET_break (0);
  1237. return;
  1238. }
  1239. tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen);
  1240. tnq->msg = &tnq[1];
  1241. iim = (struct GNUNET_EXIT_IcmpInternetMessage *) &tnq[1];
  1242. iim->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET);
  1243. iim->icmp_header = *icmp;
  1244. /* Perform ICMP protocol-translation (depending on destination AF and source AF)
  1245. and throw away ICMP payload depending on ICMP message type */
  1246. switch (af)
  1247. {
  1248. case AF_INET:
  1249. switch (icmp->type)
  1250. {
  1251. case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
  1252. if (destination->details.exit_destination.af == AF_INET6)
  1253. iim->icmp_header.type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY;
  1254. break;
  1255. case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
  1256. if (destination->details.exit_destination.af == AF_INET6)
  1257. iim->icmp_header.type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST;
  1258. break;
  1259. case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
  1260. if (destination->details.exit_destination.af == AF_INET6)
  1261. iim->icmp_header.type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE;
  1262. /* throw away IP-payload, exit will have to make it up anyway */
  1263. payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
  1264. break;
  1265. case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
  1266. if (destination->details.exit_destination.af == AF_INET6)
  1267. iim->icmp_header.type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED;
  1268. /* throw away IP-payload, exit will have to make it up anyway */
  1269. payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
  1270. break;
  1271. case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
  1272. if (destination->details.exit_destination.af == AF_INET6)
  1273. {
  1274. GNUNET_STATISTICS_update (stats,
  1275. gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"),
  1276. 1, GNUNET_NO);
  1277. GNUNET_free (tnq);
  1278. return;
  1279. }
  1280. /* throw away IP-payload, exit will have to make it up anyway */
  1281. payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
  1282. break;
  1283. default:
  1284. GNUNET_STATISTICS_update (stats,
  1285. gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
  1286. 1, GNUNET_NO);
  1287. GNUNET_free (tnq);
  1288. return;
  1289. }
  1290. /* end of AF_INET */
  1291. break;
  1292. case AF_INET6:
  1293. switch (icmp->type)
  1294. {
  1295. case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
  1296. if (destination->details.exit_destination.af == AF_INET6)
  1297. iim->icmp_header.type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE;
  1298. /* throw away IP-payload, exit will have to make it up anyway */
  1299. payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
  1300. break;
  1301. case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
  1302. if (destination->details.exit_destination.af == AF_INET)
  1303. iim->icmp_header.type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED;
  1304. /* throw away IP-payload, exit will have to make it up anyway */
  1305. payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
  1306. break;
  1307. case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
  1308. if (destination->details.exit_destination.af == AF_INET)
  1309. {
  1310. GNUNET_STATISTICS_update (stats,
  1311. gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
  1312. 1, GNUNET_NO);
  1313. GNUNET_free (tnq);
  1314. return;
  1315. }
  1316. /* throw away IP-payload, exit will have to make it up anyway */
  1317. payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
  1318. break;
  1319. case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
  1320. if (destination->details.exit_destination.af == AF_INET)
  1321. {
  1322. GNUNET_STATISTICS_update (stats,
  1323. gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
  1324. 1, GNUNET_NO);
  1325. GNUNET_free (tnq);
  1326. return;
  1327. }
  1328. /* throw away IP-payload, exit will have to make it up anyway */
  1329. payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
  1330. break;
  1331. case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
  1332. if (destination->details.exit_destination.af == AF_INET)
  1333. iim->icmp_header.type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST;
  1334. break;
  1335. case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY:
  1336. if (destination->details.exit_destination.af == AF_INET)
  1337. iim->icmp_header.type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY;
  1338. break;
  1339. default:
  1340. GNUNET_STATISTICS_update (stats,
  1341. gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
  1342. 1, GNUNET_NO);
  1343. GNUNET_free (tnq);
  1344. return;
  1345. }
  1346. /* end of AF_INET6 */
  1347. break;
  1348. default:
  1349. GNUNET_assert (0);
  1350. }
  1351. /* update length calculations, as payload_length may have changed */
  1352. mlen = sizeof (struct GNUNET_EXIT_IcmpInternetMessage) +
  1353. alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader);
  1354. tnq->len = mlen;
  1355. iim->header.size = htons ((uint16_t) mlen);
  1356. /* need to tell destination ICMP protocol family! */
  1357. iim->af = htonl (destination->details.exit_destination.af);
  1358. switch (destination->details.exit_destination.af)
  1359. {
  1360. case AF_INET:
  1361. ip4dst = (struct in_addr *) &iim[1];
  1362. *ip4dst = destination->details.exit_destination.ip.v4;
  1363. payload = &ip4dst[1];
  1364. break;
  1365. case AF_INET6:
  1366. ip6dst = (struct in6_addr *) &iim[1];
  1367. *ip6dst = destination->details.exit_destination.ip.v6;
  1368. payload = &ip6dst[1];
  1369. break;
  1370. default:
  1371. GNUNET_assert (0);
  1372. }
  1373. memcpy (payload,
  1374. &icmp[1],
  1375. payload_length - sizeof (struct GNUNET_TUN_IcmpHeader));
  1376. }
  1377. break;
  1378. default:
  1379. /* not supported above, how can we get here !? */
  1380. GNUNET_assert (0);
  1381. break;
  1382. }
  1383. send_to_channel (tnq, ts);
  1384. }
  1385. /**
  1386. * Receive packets from the helper-process (someone send to the local
  1387. * virtual channel interface). Find the destination mapping, and if it
  1388. * exists, identify the correct CADET channel (or possibly create it)
  1389. * and forward the packet.
  1390. *
  1391. * @param cls closure, NULL
  1392. * @param client NULL
  1393. * @param message message we got from the client (VPN channel interface)
  1394. */
  1395. static int
  1396. message_token (void *cls,
  1397. void *client,
  1398. const struct GNUNET_MessageHeader *message)
  1399. {
  1400. const struct GNUNET_TUN_Layer2PacketHeader *tun;
  1401. size_t mlen;
  1402. struct GNUNET_HashCode key;
  1403. struct DestinationEntry *de;
  1404. GNUNET_STATISTICS_update (stats,
  1405. gettext_noop ("# Packets received from TUN interface"),
  1406. 1, GNUNET_NO);
  1407. mlen = ntohs (message->size);
  1408. if ( (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) ||
  1409. (mlen < sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader)) )
  1410. {
  1411. GNUNET_break (0);
  1412. return GNUNET_OK;
  1413. }
  1414. tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1];
  1415. mlen -= (sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader));
  1416. switch (ntohs (tun->proto))
  1417. {
  1418. case ETH_P_IPV6:
  1419. {
  1420. const struct GNUNET_TUN_IPv6Header *pkt6;
  1421. if (mlen < sizeof (struct GNUNET_TUN_IPv6Header))
  1422. {
  1423. /* blame kernel */
  1424. GNUNET_break (0);
  1425. return GNUNET_OK;
  1426. }
  1427. pkt6 = (const struct GNUNET_TUN_IPv6Header *) &tun[1];
  1428. get_destination_key_from_ip (AF_INET6,
  1429. &pkt6->destination_address,
  1430. &key);
  1431. de = GNUNET_CONTAINER_multihashmap_get (destination_map, &key);
  1432. if (NULL == de)
  1433. {
  1434. char buf[INET6_ADDRSTRLEN];
  1435. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  1436. _("Packet received for unmapped destination `%s' (dropping it)\n"),
  1437. inet_ntop (AF_INET6,
  1438. &pkt6->destination_address,
  1439. buf,
  1440. sizeof (buf)));
  1441. return GNUNET_OK;
  1442. }
  1443. route_packet (de,
  1444. AF_INET6,
  1445. pkt6->next_header,
  1446. &pkt6->source_address,
  1447. &pkt6->destination_address,
  1448. &pkt6[1],
  1449. mlen - sizeof (struct GNUNET_TUN_IPv6Header));
  1450. }
  1451. break;
  1452. case ETH_P_IPV4:
  1453. {
  1454. struct GNUNET_TUN_IPv4Header *pkt4;
  1455. if (mlen < sizeof (struct GNUNET_TUN_IPv4Header))
  1456. {
  1457. /* blame kernel */
  1458. GNUNET_break (0);
  1459. return GNUNET_OK;
  1460. }
  1461. pkt4 = (struct GNUNET_TUN_IPv4Header *) &tun[1];
  1462. get_destination_key_from_ip (AF_INET,
  1463. &pkt4->destination_address,
  1464. &key);
  1465. de = GNUNET_CONTAINER_multihashmap_get (destination_map, &key);
  1466. if (NULL == de)
  1467. {
  1468. char buf[INET_ADDRSTRLEN];
  1469. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  1470. _("Packet received for unmapped destination `%s' (dropping it)\n"),
  1471. inet_ntop (AF_INET,
  1472. &pkt4->destination_address,
  1473. buf,
  1474. sizeof (buf)));
  1475. return GNUNET_OK;
  1476. }
  1477. if (pkt4->header_length * 4 != sizeof (struct GNUNET_TUN_IPv4Header))
  1478. {
  1479. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  1480. _("Received IPv4 packet with options (dropping it)\n"));
  1481. return GNUNET_OK;
  1482. }
  1483. route_packet (de,
  1484. AF_INET,
  1485. pkt4->protocol,
  1486. &pkt4->source_address,
  1487. &pkt4->destination_address,
  1488. &pkt4[1],
  1489. mlen - sizeof (struct GNUNET_TUN_IPv4Header));
  1490. }
  1491. break;
  1492. default:
  1493. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  1494. _("Received packet of unknown protocol %d from TUN (dropping it)\n"),
  1495. (unsigned int) ntohs (tun->proto));
  1496. break;
  1497. }
  1498. return GNUNET_OK;
  1499. }
  1500. /**
  1501. * Synthesize a plausible ICMP payload for an ICMP error
  1502. * response on the given channel.
  1503. *
  1504. * @param ts channel information
  1505. * @param ipp IPv4 header to fill in (ICMP payload)
  1506. * @param udp "UDP" header to fill in (ICMP payload); might actually
  1507. * also be the first 8 bytes of the TCP header
  1508. */
  1509. static void
  1510. make_up_icmpv4_payload (struct ChannelState *ts,
  1511. struct GNUNET_TUN_IPv4Header *ipp,
  1512. struct GNUNET_TUN_UdpHeader *udp)
  1513. {
  1514. GNUNET_TUN_initialize_ipv4_header (ipp,
  1515. ts->protocol,
  1516. sizeof (struct GNUNET_TUN_TcpHeader),
  1517. &ts->source_ip.v4,
  1518. &ts->destination_ip.v4);
  1519. udp->source_port = htons (ts->source_port);
  1520. udp->destination_port = htons (ts->destination_port);
  1521. udp->len = htons (0);
  1522. udp->crc = htons (0);
  1523. }
  1524. /**
  1525. * Synthesize a plausible ICMP payload for an ICMP error
  1526. * response on the given channel.
  1527. *
  1528. * @param ts channel information
  1529. * @param ipp IPv6 header to fill in (ICMP payload)
  1530. * @param udp "UDP" header to fill in (ICMP payload); might actually
  1531. * also be the first 8 bytes of the TCP header
  1532. */
  1533. static void
  1534. make_up_icmpv6_payload (struct ChannelState *ts,
  1535. struct GNUNET_TUN_IPv6Header *ipp,
  1536. struct GNUNET_TUN_UdpHeader *udp)
  1537. {
  1538. GNUNET_TUN_initialize_ipv6_header (ipp,
  1539. ts->protocol,
  1540. sizeof (struct GNUNET_TUN_TcpHeader),
  1541. &ts->source_ip.v6,
  1542. &ts->destination_ip.v6);
  1543. udp->source_port = htons (ts->source_port);
  1544. udp->destination_port = htons (ts->destination_port);
  1545. udp->len = htons (0);
  1546. udp->crc = htons (0);
  1547. }
  1548. /**
  1549. * We got an ICMP packet back from the CADET channel. Pass it on to the
  1550. * local virtual interface via the helper.
  1551. *
  1552. * @param cls closure, NULL
  1553. * @param channel connection to the other end
  1554. * @param channel_ctx pointer to our 'struct ChannelState *'
  1555. * @param message the actual message
  1556. * @return #GNUNET_OK to keep the connection open,
  1557. * #GNUNET_SYSERR to close it (signal serious error)
  1558. */
  1559. static int
  1560. receive_icmp_back (void *cls,
  1561. struct GNUNET_CADET_Channel *channel,
  1562. void **channel_ctx,
  1563. const struct GNUNET_MessageHeader *message)
  1564. {
  1565. struct ChannelState *ts = *channel_ctx;
  1566. const struct GNUNET_EXIT_IcmpToVPNMessage *i2v;
  1567. size_t mlen;
  1568. GNUNET_STATISTICS_update (stats,
  1569. gettext_noop ("# ICMP packets received from cadet"),
  1570. 1, GNUNET_NO);
  1571. mlen = ntohs (message->size);
  1572. if (mlen < sizeof (struct GNUNET_EXIT_IcmpToVPNMessage))
  1573. {
  1574. GNUNET_break_op (0);
  1575. return GNUNET_SYSERR;
  1576. }
  1577. if (NULL == ts->heap_node)
  1578. {
  1579. GNUNET_break_op (0);
  1580. return GNUNET_SYSERR;
  1581. }
  1582. if (AF_UNSPEC == ts->af)
  1583. {
  1584. GNUNET_break_op (0);
  1585. return GNUNET_SYSERR;
  1586. }
  1587. i2v = (const struct GNUNET_EXIT_IcmpToVPNMessage *) message;
  1588. mlen -= sizeof (struct GNUNET_EXIT_IcmpToVPNMessage);
  1589. {
  1590. char sbuf[INET6_ADDRSTRLEN];
  1591. char dbuf[INET6_ADDRSTRLEN];
  1592. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  1593. "Received ICMP packet from cadet, sending %u bytes from %s -> %s via TUN\n",
  1594. (unsigned int) mlen,
  1595. inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)),
  1596. inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf)));
  1597. }
  1598. switch (ts->af)
  1599. {
  1600. case AF_INET:
  1601. {
  1602. size_t size = sizeof (struct GNUNET_TUN_IPv4Header)
  1603. + sizeof (struct GNUNET_TUN_IcmpHeader)
  1604. + sizeof (struct GNUNET_MessageHeader) +
  1605. sizeof (struct GNUNET_TUN_Layer2PacketHeader) +
  1606. mlen;
  1607. {
  1608. /* reserve some extra space in case we have an ICMP type here where
  1609. we will need to make up the payload ourselves */
  1610. char buf[size + sizeof (struct GNUNET_TUN_IPv4Header) + 8] GNUNET_ALIGN;
  1611. struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
  1612. struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1];
  1613. struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1];
  1614. struct GNUNET_TUN_IcmpHeader *icmp = (struct GNUNET_TUN_IcmpHeader *) &ipv4[1];
  1615. msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
  1616. tun->flags = htons (0);
  1617. tun->proto = htons (ETH_P_IPV4);
  1618. GNUNET_TUN_initialize_ipv4_header (ipv4,
  1619. IPPROTO_ICMP,
  1620. sizeof (struct GNUNET_TUN_IcmpHeader) + mlen,
  1621. &ts->destination_ip.v4,
  1622. &ts->source_ip.v4);
  1623. *icmp = i2v->icmp_header;
  1624. memcpy (&icmp[1],
  1625. &i2v[1],
  1626. mlen);
  1627. /* For some ICMP types, we need to adjust (make up) the payload here.
  1628. Also, depending on the AF used on the other side, we have to
  1629. do ICMP PT (translate ICMP types) */
  1630. switch (ntohl (i2v->af))
  1631. {
  1632. case AF_INET:
  1633. switch (icmp->type)
  1634. {
  1635. case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
  1636. case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
  1637. break;
  1638. case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
  1639. case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
  1640. case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
  1641. {
  1642. struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) &icmp[1];
  1643. struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1];
  1644. if (mlen != 0)
  1645. {
  1646. /* sender did not strip ICMP payload? */
  1647. GNUNET_break_op (0);
  1648. return GNUNET_SYSERR;
  1649. }
  1650. size += sizeof (struct GNUNET_TUN_IPv4Header) + 8;
  1651. GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
  1652. make_up_icmpv4_payload (ts, ipp, udp);
  1653. }
  1654. break;
  1655. default:
  1656. GNUNET_break_op (0);
  1657. GNUNET_STATISTICS_update (stats,
  1658. gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
  1659. 1, GNUNET_NO);
  1660. return GNUNET_SYSERR;
  1661. }
  1662. /* end AF_INET */
  1663. break;
  1664. case AF_INET6:
  1665. /* ICMP PT 6-to-4 and possibly making up payloads */
  1666. switch (icmp->type)
  1667. {
  1668. case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
  1669. icmp->type = GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE;
  1670. {
  1671. struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) &icmp[1];
  1672. struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1];
  1673. if (mlen != 0)
  1674. {
  1675. /* sender did not strip ICMP payload? */
  1676. GNUNET_break_op (0);
  1677. return GNUNET_SYSERR;
  1678. }
  1679. size += sizeof (struct GNUNET_TUN_IPv4Header) + 8;
  1680. GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
  1681. make_up_icmpv4_payload (ts, ipp, udp);
  1682. }
  1683. break;
  1684. case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
  1685. icmp->type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED;
  1686. {
  1687. struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) &icmp[1];
  1688. struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1];
  1689. if (mlen != 0)
  1690. {
  1691. /* sender did not strip ICMP payload? */
  1692. GNUNET_break_op (0);
  1693. return GNUNET_SYSERR;
  1694. }
  1695. size += sizeof (struct GNUNET_TUN_IPv4Header) + 8;
  1696. GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
  1697. make_up_icmpv4_payload (ts, ipp, udp);
  1698. }
  1699. break;
  1700. case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
  1701. case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
  1702. GNUNET_STATISTICS_update (stats,
  1703. gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
  1704. 1, GNUNET_NO);
  1705. return GNUNET_OK;
  1706. case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
  1707. icmp->type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST;
  1708. break;
  1709. case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY:
  1710. icmp->type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY;
  1711. break;
  1712. default:
  1713. GNUNET_break_op (0);
  1714. GNUNET_STATISTICS_update (stats,
  1715. gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
  1716. 1, GNUNET_NO);
  1717. return GNUNET_SYSERR;
  1718. }
  1719. /* end AF_INET6 */
  1720. break;
  1721. default:
  1722. GNUNET_break_op (0);
  1723. return GNUNET_SYSERR;
  1724. }
  1725. msg->size = htons (size);
  1726. GNUNET_TUN_calculate_icmp_checksum (icmp,
  1727. &i2v[1],
  1728. mlen);
  1729. (void) GNUNET_HELPER_send (helper_handle,
  1730. msg,
  1731. GNUNET_YES,
  1732. NULL, NULL);
  1733. }
  1734. }
  1735. break;
  1736. case AF_INET6:
  1737. {
  1738. size_t size = sizeof (struct GNUNET_TUN_IPv6Header)
  1739. + sizeof (struct GNUNET_TUN_IcmpHeader)
  1740. + sizeof (struct GNUNET_MessageHeader) +
  1741. sizeof (struct GNUNET_TUN_Layer2PacketHeader) +
  1742. mlen;
  1743. {
  1744. char buf[size + sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
  1745. struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
  1746. struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1];
  1747. struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1];
  1748. struct GNUNET_TUN_IcmpHeader *icmp = (struct GNUNET_TUN_IcmpHeader *) &ipv6[1];
  1749. msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
  1750. tun->flags = htons (0);
  1751. tun->proto = htons (ETH_P_IPV6);
  1752. GNUNET_TUN_initialize_ipv6_header (ipv6,
  1753. IPPROTO_ICMPV6,
  1754. sizeof (struct GNUNET_TUN_IcmpHeader) + mlen,
  1755. &ts->destination_ip.v6,
  1756. &ts->source_ip.v6);
  1757. *icmp = i2v->icmp_header;
  1758. memcpy (&icmp[1],
  1759. &i2v[1],
  1760. mlen);
  1761. /* For some ICMP types, we need to adjust (make up) the payload here.
  1762. Also, depending on the AF used on the other side, we have to
  1763. do ICMP PT (translate ICMP types) */
  1764. switch (ntohl (i2v->af))
  1765. {
  1766. case AF_INET:
  1767. /* ICMP PT 4-to-6 and possibly making up payloads */
  1768. switch (icmp->type)
  1769. {
  1770. case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
  1771. icmp->type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY;
  1772. break;
  1773. case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
  1774. icmp->type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST;
  1775. break;
  1776. case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
  1777. icmp->type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE;
  1778. {
  1779. struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) &icmp[1];
  1780. struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1];
  1781. if (mlen != 0)
  1782. {
  1783. /* sender did not strip ICMP payload? */
  1784. GNUNET_break_op (0);
  1785. return GNUNET_SYSERR;
  1786. }
  1787. size += sizeof (struct GNUNET_TUN_IPv6Header) + 8;
  1788. GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
  1789. make_up_icmpv6_payload (ts, ipp, udp);
  1790. }
  1791. break;
  1792. case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
  1793. icmp->type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED;
  1794. {
  1795. struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) &icmp[1];
  1796. struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1];
  1797. if (mlen != 0)
  1798. {
  1799. /* sender did not strip ICMP payload? */
  1800. GNUNET_break_op (0);
  1801. return GNUNET_SYSERR;
  1802. }
  1803. size += sizeof (struct GNUNET_TUN_IPv6Header) + 8;
  1804. GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
  1805. make_up_icmpv6_payload (ts, ipp, udp);
  1806. }
  1807. break;
  1808. case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
  1809. GNUNET_STATISTICS_update (stats,
  1810. gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"),
  1811. 1, GNUNET_NO);
  1812. return GNUNET_OK;
  1813. default:
  1814. GNUNET_break_op (0);
  1815. GNUNET_STATISTICS_update (stats,
  1816. gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
  1817. 1, GNUNET_NO);
  1818. return GNUNET_SYSERR;
  1819. }
  1820. /* end AF_INET */
  1821. break;
  1822. case AF_INET6:
  1823. switch (icmp->type)
  1824. {
  1825. case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
  1826. case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
  1827. case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
  1828. case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
  1829. {
  1830. struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) &icmp[1];
  1831. struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1];
  1832. if (mlen != 0)
  1833. {
  1834. /* sender did not strip ICMP payload? */
  1835. GNUNET_break_op (0);
  1836. return GNUNET_SYSERR;
  1837. }
  1838. size += sizeof (struct GNUNET_TUN_IPv6Header) + 8;
  1839. GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
  1840. make_up_icmpv6_payload (ts, ipp, udp);
  1841. }
  1842. break;
  1843. case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
  1844. break;
  1845. default:
  1846. GNUNET_break_op (0);
  1847. GNUNET_STATISTICS_update (stats,
  1848. gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
  1849. 1, GNUNET_NO);
  1850. return GNUNET_SYSERR;
  1851. }
  1852. /* end AF_INET6 */
  1853. break;
  1854. default:
  1855. GNUNET_break_op (0);
  1856. return GNUNET_SYSERR;
  1857. }
  1858. msg->size = htons (size);
  1859. GNUNET_TUN_calculate_icmp_checksum (icmp,
  1860. &i2v[1], mlen);
  1861. (void) GNUNET_HELPER_send (helper_handle,
  1862. msg,
  1863. GNUNET_YES,
  1864. NULL, NULL);
  1865. }
  1866. }
  1867. break;
  1868. default:
  1869. GNUNET_assert (0);
  1870. }
  1871. GNUNET_CONTAINER_heap_update_cost (channel_heap,
  1872. ts->heap_node,
  1873. GNUNET_TIME_absolute_get ().abs_value_us);
  1874. return GNUNET_OK;
  1875. }
  1876. /**
  1877. * We got a UDP packet back from the CADET channel. Pass it on to the
  1878. * local virtual interface via the helper.
  1879. *
  1880. * @param cls closure, NULL
  1881. * @param channel connection to the other end
  1882. * @param channel_ctx pointer to our 'struct ChannelState *'
  1883. * @param message the actual message
  1884. * @return #GNUNET_OK to keep the connection open,
  1885. * #GNUNET_SYSERR to close it (signal serious error)
  1886. */
  1887. static int
  1888. receive_udp_back (void *cls,
  1889. struct GNUNET_CADET_Channel *channel,
  1890. void **channel_ctx,
  1891. const struct GNUNET_MessageHeader *message)
  1892. {
  1893. struct ChannelState *ts = *channel_ctx;
  1894. const struct GNUNET_EXIT_UdpReplyMessage *reply;
  1895. size_t mlen;
  1896. GNUNET_STATISTICS_update (stats,
  1897. gettext_noop ("# UDP packets received from cadet"),
  1898. 1, GNUNET_NO);
  1899. mlen = ntohs (message->size);
  1900. if (mlen < sizeof (struct GNUNET_EXIT_UdpReplyMessage))
  1901. {
  1902. GNUNET_break_op (0);
  1903. return GNUNET_SYSERR;
  1904. }
  1905. if (NULL == ts->heap_node)
  1906. {
  1907. GNUNET_break_op (0);
  1908. return GNUNET_SYSERR;
  1909. }
  1910. if (AF_UNSPEC == ts->af)
  1911. {
  1912. GNUNET_break_op (0);
  1913. return GNUNET_SYSERR;
  1914. }
  1915. reply = (const struct GNUNET_EXIT_UdpReplyMessage *) message;
  1916. mlen -= sizeof (struct GNUNET_EXIT_UdpReplyMessage);
  1917. {
  1918. char sbuf[INET6_ADDRSTRLEN];
  1919. char dbuf[INET6_ADDRSTRLEN];
  1920. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  1921. "Received UDP reply from cadet, sending %u bytes from %s:%u -> %s:%u via TUN\n",
  1922. (unsigned int) mlen,
  1923. inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)),
  1924. ts->destination_port,
  1925. inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf)),
  1926. ts->source_port);
  1927. }
  1928. switch (ts->af)
  1929. {
  1930. case AF_INET:
  1931. {
  1932. size_t size = sizeof (struct GNUNET_TUN_IPv4Header)
  1933. + sizeof (struct GNUNET_TUN_UdpHeader)
  1934. + sizeof (struct GNUNET_MessageHeader) +
  1935. sizeof (struct GNUNET_TUN_Layer2PacketHeader) +
  1936. mlen;
  1937. {
  1938. char buf[size] GNUNET_ALIGN;
  1939. struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
  1940. struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1];
  1941. struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1];
  1942. struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipv4[1];
  1943. msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
  1944. msg->size = htons (size);
  1945. tun->flags = htons (0);
  1946. tun->proto = htons (ETH_P_IPV4);
  1947. GNUNET_TUN_initialize_ipv4_header (ipv4,
  1948. IPPROTO_UDP,
  1949. sizeof (struct GNUNET_TUN_UdpHeader) + mlen,
  1950. &ts->destination_ip.v4,
  1951. &ts->source_ip.v4);
  1952. if (0 == ntohs (reply->source_port))
  1953. udp->source_port = htons (ts->destination_port);
  1954. else
  1955. udp->source_port = reply->source_port;
  1956. if (0 == ntohs (reply->destination_port))
  1957. udp->destination_port = htons (ts->source_port);
  1958. else
  1959. udp->destination_port = reply->destination_port;
  1960. udp->len = htons (mlen + sizeof (struct GNUNET_TUN_UdpHeader));
  1961. GNUNET_TUN_calculate_udp4_checksum (ipv4,
  1962. udp,
  1963. &reply[1],
  1964. mlen);
  1965. memcpy (&udp[1],
  1966. &reply[1],
  1967. mlen);
  1968. (void) GNUNET_HELPER_send (helper_handle,
  1969. msg,
  1970. GNUNET_YES,
  1971. NULL, NULL);
  1972. }
  1973. }
  1974. break;
  1975. case AF_INET6:
  1976. {
  1977. size_t size = sizeof (struct GNUNET_TUN_IPv6Header)
  1978. + sizeof (struct GNUNET_TUN_UdpHeader)
  1979. + sizeof (struct GNUNET_MessageHeader) +
  1980. sizeof (struct GNUNET_TUN_Layer2PacketHeader) +
  1981. mlen;
  1982. {
  1983. char buf[size] GNUNET_ALIGN;
  1984. struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
  1985. struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1];
  1986. struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1];
  1987. struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipv6[1];
  1988. msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
  1989. msg->size = htons (size);
  1990. tun->flags = htons (0);
  1991. tun->proto = htons (ETH_P_IPV6);
  1992. GNUNET_TUN_initialize_ipv6_header (ipv6,
  1993. IPPROTO_UDP,
  1994. sizeof (struct GNUNET_TUN_UdpHeader) + mlen,
  1995. &ts->destination_ip.v6,
  1996. &ts->source_ip.v6);
  1997. if (0 == ntohs (reply->source_port))
  1998. udp->source_port = htons (ts->destination_port);
  1999. else
  2000. udp->source_port = reply->source_port;
  2001. if (0 == ntohs (reply->destination_port))
  2002. udp->destination_port = htons (ts->source_port);
  2003. else
  2004. udp->destination_port = reply->destination_port;
  2005. udp->len = htons (mlen + sizeof (struct GNUNET_TUN_UdpHeader));
  2006. GNUNET_TUN_calculate_udp6_checksum (ipv6,
  2007. udp,
  2008. &reply[1], mlen);
  2009. memcpy (&udp[1],
  2010. &reply[1],
  2011. mlen);
  2012. (void) GNUNET_HELPER_send (helper_handle,
  2013. msg,
  2014. GNUNET_YES,
  2015. NULL, NULL);
  2016. }
  2017. }
  2018. break;
  2019. default:
  2020. GNUNET_assert (0);
  2021. }
  2022. GNUNET_CONTAINER_heap_update_cost (channel_heap,
  2023. ts->heap_node,
  2024. GNUNET_TIME_absolute_get ().abs_value_us);
  2025. return GNUNET_OK;
  2026. }
  2027. /**
  2028. * We got a TCP packet back from the CADET channel. Pass it on to the
  2029. * local virtual interface via the helper.
  2030. *
  2031. * @param cls closure, NULL
  2032. * @param channel connection to the other end
  2033. * @param channel_ctx pointer to our `struct ChannelState *`
  2034. * @param message the actual message
  2035. * @return #GNUNET_OK to keep the connection open,
  2036. * #GNUNET_SYSERR to close it (signal serious error)
  2037. */
  2038. static int
  2039. receive_tcp_back (void *cls,
  2040. struct GNUNET_CADET_Channel *channel,
  2041. void **channel_ctx,
  2042. const struct GNUNET_MessageHeader *message)
  2043. {
  2044. struct ChannelState *ts = *channel_ctx;
  2045. const struct GNUNET_EXIT_TcpDataMessage *data;
  2046. size_t mlen;
  2047. GNUNET_STATISTICS_update (stats,
  2048. gettext_noop ("# TCP packets received from cadet"),
  2049. 1, GNUNET_NO);
  2050. mlen = ntohs (message->size);
  2051. if (mlen < sizeof (struct GNUNET_EXIT_TcpDataMessage))
  2052. {
  2053. GNUNET_break_op (0);
  2054. return GNUNET_SYSERR;
  2055. }
  2056. if (NULL == ts->heap_node)
  2057. {
  2058. GNUNET_break_op (0);
  2059. return GNUNET_SYSERR;
  2060. }
  2061. data = (const struct GNUNET_EXIT_TcpDataMessage *) message;
  2062. mlen -= sizeof (struct GNUNET_EXIT_TcpDataMessage);
  2063. {
  2064. char sbuf[INET6_ADDRSTRLEN];
  2065. char dbuf[INET6_ADDRSTRLEN];
  2066. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  2067. "Received TCP reply from cadet, sending %u bytes from %s:%u -> %s:%u via TUN\n",
  2068. (unsigned int) mlen,
  2069. inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)),
  2070. ts->destination_port,
  2071. inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf)),
  2072. ts->source_port);
  2073. }
  2074. if (data->tcp_header.off * 4 < sizeof (struct GNUNET_TUN_TcpHeader))
  2075. {
  2076. GNUNET_break_op (0);
  2077. return GNUNET_SYSERR;
  2078. }
  2079. switch (ts->af)
  2080. {
  2081. case AF_INET:
  2082. {
  2083. size_t size = sizeof (struct GNUNET_TUN_IPv4Header)
  2084. + sizeof (struct GNUNET_TUN_TcpHeader)
  2085. + sizeof (struct GNUNET_MessageHeader) +
  2086. sizeof (struct GNUNET_TUN_Layer2PacketHeader) +
  2087. mlen;
  2088. {
  2089. char buf[size] GNUNET_ALIGN;
  2090. struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
  2091. struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1];
  2092. struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1];
  2093. struct GNUNET_TUN_TcpHeader *tcp = (struct GNUNET_TUN_TcpHeader *) &ipv4[1];
  2094. msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
  2095. msg->size = htons (size);
  2096. tun->flags = htons (0);
  2097. tun->proto = htons (ETH_P_IPV4);
  2098. GNUNET_TUN_initialize_ipv4_header (ipv4,
  2099. IPPROTO_TCP,
  2100. sizeof (struct GNUNET_TUN_TcpHeader) + mlen,
  2101. &ts->destination_ip.v4,
  2102. &ts->source_ip.v4);
  2103. *tcp = data->tcp_header;
  2104. tcp->source_port = htons (ts->destination_port);
  2105. tcp->destination_port = htons (ts->source_port);
  2106. GNUNET_TUN_calculate_tcp4_checksum (ipv4,
  2107. tcp,
  2108. &data[1],
  2109. mlen);
  2110. memcpy (&tcp[1],
  2111. &data[1],
  2112. mlen);
  2113. (void) GNUNET_HELPER_send (helper_handle,
  2114. msg,
  2115. GNUNET_YES,
  2116. NULL, NULL);
  2117. }
  2118. }
  2119. break;
  2120. case AF_INET6:
  2121. {
  2122. size_t size = sizeof (struct GNUNET_TUN_IPv6Header)
  2123. + sizeof (struct GNUNET_TUN_TcpHeader)
  2124. + sizeof (struct GNUNET_MessageHeader) +
  2125. sizeof (struct GNUNET_TUN_Layer2PacketHeader) +
  2126. mlen;
  2127. {
  2128. char buf[size] GNUNET_ALIGN;
  2129. struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
  2130. struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1];
  2131. struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1];
  2132. struct GNUNET_TUN_TcpHeader *tcp = (struct GNUNET_TUN_TcpHeader *) &ipv6[1];
  2133. msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
  2134. msg->size = htons (size);
  2135. tun->flags = htons (0);
  2136. tun->proto = htons (ETH_P_IPV6);
  2137. GNUNET_TUN_initialize_ipv6_header (ipv6,
  2138. IPPROTO_TCP,
  2139. sizeof (struct GNUNET_TUN_TcpHeader) + mlen,
  2140. &ts->destination_ip.v6,
  2141. &ts->source_ip.v6);
  2142. *tcp = data->tcp_header;
  2143. tcp->source_port = htons (ts->destination_port);
  2144. tcp->destination_port = htons (ts->source_port);
  2145. GNUNET_TUN_calculate_tcp6_checksum (ipv6,
  2146. tcp,
  2147. &data[1],
  2148. mlen);
  2149. memcpy (&tcp[1],
  2150. &data[1],
  2151. mlen);
  2152. (void) GNUNET_HELPER_send (helper_handle,
  2153. msg,
  2154. GNUNET_YES,
  2155. NULL, NULL);
  2156. }
  2157. }
  2158. break;
  2159. }
  2160. GNUNET_CONTAINER_heap_update_cost (channel_heap,
  2161. ts->heap_node,
  2162. GNUNET_TIME_absolute_get ().abs_value_us);
  2163. return GNUNET_OK;
  2164. }
  2165. /**
  2166. * Allocate an IPv4 address from the range of the channel
  2167. * for a new redirection.
  2168. *
  2169. * @param v4 where to store the address
  2170. * @return #GNUNET_OK on success,
  2171. * #GNUNET_SYSERR on error
  2172. */
  2173. static int
  2174. allocate_v4_address (struct in_addr *v4)
  2175. {
  2176. const char *ipv4addr = vpn_argv[4];
  2177. const char *ipv4mask = vpn_argv[5];
  2178. struct in_addr addr;
  2179. struct in_addr mask;
  2180. struct in_addr rnd;
  2181. struct GNUNET_HashCode key;
  2182. unsigned int tries;
  2183. GNUNET_assert (1 == inet_pton (AF_INET, ipv4addr, &addr));
  2184. GNUNET_assert (1 == inet_pton (AF_INET, ipv4mask, &mask));
  2185. /* Given 192.168.0.1/255.255.0.0, we want a mask
  2186. of '192.168.255.255', thus: */
  2187. mask.s_addr = addr.s_addr | ~mask.s_addr;
  2188. tries = 0;
  2189. do
  2190. {
  2191. tries++;
  2192. if (tries > 16)
  2193. {
  2194. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  2195. _("Failed to find unallocated IPv4 address in VPN's range\n"));
  2196. return GNUNET_SYSERR;
  2197. }
  2198. /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
  2199. rnd.s_addr = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
  2200. UINT32_MAX);
  2201. v4->s_addr = (addr.s_addr | rnd.s_addr) & mask.s_addr;
  2202. get_destination_key_from_ip (AF_INET,
  2203. v4,
  2204. &key);
  2205. }
  2206. while ( (GNUNET_YES ==
  2207. GNUNET_CONTAINER_multihashmap_contains (destination_map,
  2208. &key)) ||
  2209. (v4->s_addr == addr.s_addr) ||
  2210. (v4->s_addr == mask.s_addr) );
  2211. return GNUNET_OK;
  2212. }
  2213. /**
  2214. * Allocate an IPv6 address from the range of the channel
  2215. * for a new redirection.
  2216. *
  2217. * @param v6 where to store the address
  2218. * @return #GNUNET_OK on success,
  2219. * #GNUNET_SYSERR on error
  2220. */
  2221. static int
  2222. allocate_v6_address (struct in6_addr *v6)
  2223. {
  2224. const char *ipv6addr = vpn_argv[2];
  2225. struct in6_addr addr;
  2226. struct in6_addr mask;
  2227. struct in6_addr rnd;
  2228. int i;
  2229. struct GNUNET_HashCode key;
  2230. unsigned int tries;
  2231. GNUNET_assert (1 == inet_pton (AF_INET6, ipv6addr, &addr));
  2232. GNUNET_assert (ipv6prefix < 128);
  2233. /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
  2234. thus: */
  2235. mask = addr;
  2236. for (i=127;i>=ipv6prefix;i--)
  2237. mask.s6_addr[i / 8] |= (1 << (i % 8));
  2238. /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
  2239. tries = 0;
  2240. do
  2241. {
  2242. tries++;
  2243. if (tries > 16)
  2244. {
  2245. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  2246. _("Failed to find unallocated IPv6 address in VPN's range\n"));
  2247. return GNUNET_SYSERR;
  2248. }
  2249. for (i=0;i<16;i++)
  2250. {
  2251. rnd.s6_addr[i] = (unsigned char) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
  2252. 256);
  2253. v6->s6_addr[i]
  2254. = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
  2255. }
  2256. get_destination_key_from_ip (AF_INET6,
  2257. v6,
  2258. &key);
  2259. }
  2260. while ( (GNUNET_YES ==
  2261. GNUNET_CONTAINER_multihashmap_contains (destination_map,
  2262. &key)) ||
  2263. (0 == memcmp (v6,
  2264. &addr,
  2265. sizeof (struct in6_addr))) ||
  2266. (0 == memcmp (v6,
  2267. &mask,
  2268. sizeof (struct in6_addr))) );
  2269. return GNUNET_OK;
  2270. }
  2271. /**
  2272. * Free resources occupied by a destination entry.
  2273. *
  2274. * @param de entry to free
  2275. */
  2276. static void
  2277. free_destination_entry (struct DestinationEntry *de)
  2278. {
  2279. struct DestinationChannel *dt;
  2280. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  2281. "Cleaning up destination entry\n");
  2282. GNUNET_STATISTICS_update (stats,
  2283. gettext_noop ("# Active destinations"),
  2284. -1, GNUNET_NO);
  2285. while (NULL != (dt = de->dt_head))
  2286. {
  2287. GNUNET_CONTAINER_DLL_remove (de->dt_head,
  2288. de->dt_tail,
  2289. dt);
  2290. if (NULL != dt->ts)
  2291. {
  2292. free_channel_state (dt->ts);
  2293. GNUNET_assert (NULL == dt->ts);
  2294. }
  2295. GNUNET_free (dt);
  2296. }
  2297. if (NULL != de->heap_node)
  2298. {
  2299. GNUNET_CONTAINER_heap_remove_node (de->heap_node);
  2300. de->heap_node = NULL;
  2301. GNUNET_assert (GNUNET_YES ==
  2302. GNUNET_CONTAINER_multihashmap_remove (destination_map,
  2303. &de->key,
  2304. de));
  2305. }
  2306. GNUNET_free (de);
  2307. }
  2308. /**
  2309. * We have too many active destinations. Clean up the oldest destination.
  2310. *
  2311. * @param except destination that must NOT be cleaned up, even if it is the oldest
  2312. */
  2313. static void
  2314. expire_destination (struct DestinationEntry *except)
  2315. {
  2316. struct DestinationEntry *de;
  2317. de = GNUNET_CONTAINER_heap_peek (destination_heap);
  2318. GNUNET_assert (NULL != de);
  2319. if (except == de)
  2320. return; /* can't do this */
  2321. free_destination_entry (de);
  2322. }
  2323. /**
  2324. * Allocate an IP address for the response.
  2325. *
  2326. * @param result_af desired address family; set to the actual
  2327. * address family; can initially be AF_UNSPEC if there
  2328. * is no preference; will be set to AF_UNSPEC if the
  2329. * allocation failed
  2330. * @param addr set to either v4 or v6 depending on which
  2331. * storage location was used; set to NULL if allocation failed
  2332. * @param v4 storage space for an IPv4 address
  2333. * @param v6 storage space for an IPv6 address
  2334. * @return #GNUNET_OK normally, #GNUNET_SYSERR if `* result_af` was
  2335. * an unsupported address family (not AF_INET, AF_INET6 or AF_UNSPEC)
  2336. */
  2337. static int
  2338. allocate_response_ip (int *result_af,
  2339. void **addr,
  2340. struct in_addr *v4,
  2341. struct in6_addr *v6)
  2342. {
  2343. *addr = NULL;
  2344. switch (*result_af)
  2345. {
  2346. case AF_INET:
  2347. if (GNUNET_OK !=
  2348. allocate_v4_address (v4))
  2349. *result_af = AF_UNSPEC;
  2350. else
  2351. *addr = v4;
  2352. break;
  2353. case AF_INET6:
  2354. if (GNUNET_OK !=
  2355. allocate_v6_address (v6))
  2356. *result_af = AF_UNSPEC;
  2357. else
  2358. *addr = v6;
  2359. break;
  2360. case AF_UNSPEC:
  2361. if (GNUNET_OK ==
  2362. allocate_v4_address (v4))
  2363. {
  2364. *addr = v4;
  2365. *result_af = AF_INET;
  2366. }
  2367. else if (GNUNET_OK ==
  2368. allocate_v6_address (v6))
  2369. {
  2370. *addr = v6;
  2371. *result_af = AF_INET6;
  2372. }
  2373. break;
  2374. default:
  2375. GNUNET_break (0);
  2376. return GNUNET_SYSERR;
  2377. }
  2378. return GNUNET_OK;
  2379. }
  2380. /**
  2381. * A client asks us to setup a redirection via some exit node to a
  2382. * particular IP. Setup the redirection and give the client the
  2383. * allocated IP.
  2384. *
  2385. * @param cls unused
  2386. * @param client requesting client
  2387. * @param message redirection request (a `struct RedirectToIpRequestMessage`)
  2388. */
  2389. static void
  2390. service_redirect_to_ip (void *cls,
  2391. struct GNUNET_SERVER_Client *client,
  2392. const struct GNUNET_MessageHeader *message)
  2393. {
  2394. size_t mlen;
  2395. size_t alen;
  2396. const struct RedirectToIpRequestMessage *msg;
  2397. int addr_af;
  2398. int result_af;
  2399. struct in_addr v4;
  2400. struct in6_addr v6;
  2401. void *addr;
  2402. struct DestinationEntry *de;
  2403. struct GNUNET_HashCode key;
  2404. /* validate and parse request */
  2405. mlen = ntohs (message->size);
  2406. if (mlen < sizeof (struct RedirectToIpRequestMessage))
  2407. {
  2408. GNUNET_break (0);
  2409. GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
  2410. return;
  2411. }
  2412. alen = mlen - sizeof (struct RedirectToIpRequestMessage);
  2413. msg = (const struct RedirectToIpRequestMessage *) message;
  2414. addr_af = (int) htonl (msg->addr_af);
  2415. switch (addr_af)
  2416. {
  2417. case AF_INET:
  2418. if (alen != sizeof (struct in_addr))
  2419. {
  2420. GNUNET_break (0);
  2421. GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
  2422. return;
  2423. }
  2424. break;
  2425. case AF_INET6:
  2426. if (alen != sizeof (struct in6_addr))
  2427. {
  2428. GNUNET_break (0);
  2429. GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
  2430. return;
  2431. }
  2432. break;
  2433. default:
  2434. GNUNET_break (0);
  2435. GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
  2436. return;
  2437. }
  2438. /* allocate response IP */
  2439. result_af = (int) htonl (msg->result_af);
  2440. if (GNUNET_OK != allocate_response_ip (&result_af,
  2441. &addr,
  2442. &v4, &v6))
  2443. {
  2444. GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
  2445. return;
  2446. }
  2447. /* send reply with our IP address */
  2448. send_client_reply (client,
  2449. msg->request_id,
  2450. result_af,
  2451. addr);
  2452. if (result_af == AF_UNSPEC)
  2453. {
  2454. /* failure, we're done */
  2455. GNUNET_SERVER_receive_done (client, GNUNET_OK);
  2456. return;
  2457. }
  2458. {
  2459. char sbuf[INET6_ADDRSTRLEN];
  2460. char dbuf[INET6_ADDRSTRLEN];
  2461. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  2462. "Allocated address %s for redirection via exit to %s\n",
  2463. inet_ntop (result_af, addr, sbuf, sizeof (sbuf)),
  2464. inet_ntop (addr_af,
  2465. &msg[1], dbuf, sizeof (dbuf)));
  2466. }
  2467. /* setup destination record */
  2468. de = GNUNET_new (struct DestinationEntry);
  2469. de->is_service = GNUNET_NO;
  2470. de->details.exit_destination.af = addr_af;
  2471. memcpy (&de->details.exit_destination.ip,
  2472. &msg[1],
  2473. alen);
  2474. get_destination_key_from_ip (result_af,
  2475. addr,
  2476. &key);
  2477. de->key = key;
  2478. GNUNET_assert (GNUNET_OK ==
  2479. GNUNET_CONTAINER_multihashmap_put (destination_map,
  2480. &key,
  2481. de,
  2482. GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
  2483. de->heap_node = GNUNET_CONTAINER_heap_insert (destination_heap,
  2484. de,
  2485. GNUNET_TIME_absolute_ntoh (msg->expiration_time).abs_value_us);
  2486. GNUNET_STATISTICS_update (stats,
  2487. gettext_noop ("# Active destinations"),
  2488. 1, GNUNET_NO);
  2489. while (GNUNET_CONTAINER_multihashmap_size (destination_map) > max_destination_mappings)
  2490. expire_destination (de);
  2491. GNUNET_SERVER_receive_done (client, GNUNET_OK);
  2492. }
  2493. /**
  2494. * A client asks us to setup a redirection to a particular peer
  2495. * offering a service. Setup the redirection and give the client the
  2496. * allocated IP.
  2497. *
  2498. * @param cls unused
  2499. * @param client requesting client
  2500. * @param message redirection request (a `struct RedirectToPeerRequestMessage`)
  2501. */
  2502. static void
  2503. service_redirect_to_service (void *cls,
  2504. struct GNUNET_SERVER_Client *client,
  2505. const struct GNUNET_MessageHeader *message)
  2506. {
  2507. const struct RedirectToServiceRequestMessage *msg;
  2508. int result_af;
  2509. struct in_addr v4;
  2510. struct in6_addr v6;
  2511. void *addr;
  2512. struct DestinationEntry *de;
  2513. struct GNUNET_HashCode key;
  2514. struct ChannelState *ts;
  2515. struct DestinationChannel *dt;
  2516. /* parse request */
  2517. msg = (const struct RedirectToServiceRequestMessage *) message;
  2518. /* allocate response IP */
  2519. result_af = (int) htonl (msg->result_af);
  2520. if (GNUNET_OK != allocate_response_ip (&result_af,
  2521. &addr,
  2522. &v4, &v6))
  2523. {
  2524. GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
  2525. return;
  2526. }
  2527. send_client_reply (client,
  2528. msg->request_id,
  2529. result_af,
  2530. addr);
  2531. if (result_af == AF_UNSPEC)
  2532. {
  2533. /* failure, we're done */
  2534. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  2535. _("Failed to allocate IP address for new destination\n"));
  2536. GNUNET_SERVER_receive_done (client, GNUNET_OK);
  2537. return;
  2538. }
  2539. {
  2540. char sbuf[INET6_ADDRSTRLEN];
  2541. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  2542. "Allocated address %s for redirection to service %s on peer %s\n",
  2543. inet_ntop (result_af, addr, sbuf, sizeof (sbuf)),
  2544. GNUNET_h2s (&msg->service_descriptor),
  2545. GNUNET_i2s (&msg->target));
  2546. }
  2547. /* setup destination record */
  2548. de = GNUNET_new (struct DestinationEntry);
  2549. de->is_service = GNUNET_YES;
  2550. de->details.service_destination.service_descriptor = msg->service_descriptor;
  2551. de->details.service_destination.target = msg->target;
  2552. get_destination_key_from_ip (result_af,
  2553. addr,
  2554. &key);
  2555. de->key = key;
  2556. GNUNET_assert (GNUNET_OK ==
  2557. GNUNET_CONTAINER_multihashmap_put (destination_map,
  2558. &key,
  2559. de,
  2560. GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
  2561. de->heap_node = GNUNET_CONTAINER_heap_insert (destination_heap,
  2562. de,
  2563. GNUNET_TIME_absolute_ntoh (msg->expiration_time).abs_value_us);
  2564. while (GNUNET_CONTAINER_multihashmap_size (destination_map) > max_destination_mappings)
  2565. expire_destination (de);
  2566. dt = GNUNET_new (struct DestinationChannel);
  2567. dt->destination = de;
  2568. GNUNET_CONTAINER_DLL_insert (de->dt_head,
  2569. de->dt_tail,
  2570. dt);
  2571. ts = create_channel_to_destination (dt,
  2572. result_af);
  2573. switch (result_af)
  2574. {
  2575. case AF_INET:
  2576. ts->destination_ip.v4 = v4;
  2577. break;
  2578. case AF_INET6:
  2579. ts->destination_ip.v6 = v6;
  2580. break;
  2581. default:
  2582. GNUNET_assert (0);
  2583. }
  2584. /* we're done */
  2585. GNUNET_SERVER_receive_done (client, GNUNET_OK);
  2586. }
  2587. /**
  2588. * Function called whenever a channel is destroyed. Should clean up
  2589. * any associated state.
  2590. *
  2591. * @param cls closure (set from #GNUNET_CADET_connect)
  2592. * @param channel connection to the other end (henceforth invalid)
  2593. * @param channel_ctx place where local state associated
  2594. * with the channel is stored (our `struct ChannelState`)
  2595. */
  2596. static void
  2597. channel_cleaner (void *cls,
  2598. const struct GNUNET_CADET_Channel *channel,
  2599. void *channel_ctx)
  2600. {
  2601. struct ChannelState *ts = channel_ctx;
  2602. ts->channel = NULL; /* we must not call GNUNET_CADET_channel_destroy() anymore */
  2603. free_channel_state (ts);
  2604. }
  2605. /**
  2606. * Free memory occupied by an entry in the destination map.
  2607. *
  2608. * @param cls unused
  2609. * @param key unused
  2610. * @param value a `struct DestinationEntry *`
  2611. * @return #GNUNET_OK (continue to iterate)
  2612. */
  2613. static int
  2614. cleanup_destination (void *cls,
  2615. const struct GNUNET_HashCode *key,
  2616. void *value)
  2617. {
  2618. struct DestinationEntry *de = value;
  2619. free_destination_entry (de);
  2620. return GNUNET_OK;
  2621. }
  2622. /**
  2623. * Free memory occupied by an entry in the channel map.
  2624. *
  2625. * @param cls unused
  2626. * @param key unused
  2627. * @param value a `struct ChannelState *`
  2628. * @return #GNUNET_OK (continue to iterate)
  2629. */
  2630. static int
  2631. cleanup_channel (void *cls,
  2632. const struct GNUNET_HashCode *key,
  2633. void *value)
  2634. {
  2635. struct ChannelState *ts = value;
  2636. free_channel_state (ts);
  2637. return GNUNET_OK;
  2638. }
  2639. /**
  2640. * Function scheduled as very last function, cleans up after us
  2641. *
  2642. * @param cls unused
  2643. * @param tc unused
  2644. */
  2645. static void
  2646. cleanup (void *cls,
  2647. const struct GNUNET_SCHEDULER_TaskContext *tc)
  2648. {
  2649. unsigned int i;
  2650. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  2651. "VPN is shutting down\n");
  2652. if (NULL != destination_map)
  2653. {
  2654. GNUNET_CONTAINER_multihashmap_iterate (destination_map,
  2655. &cleanup_destination,
  2656. NULL);
  2657. GNUNET_CONTAINER_multihashmap_destroy (destination_map);
  2658. destination_map = NULL;
  2659. }
  2660. if (NULL != destination_heap)
  2661. {
  2662. GNUNET_CONTAINER_heap_destroy (destination_heap);
  2663. destination_heap = NULL;
  2664. }
  2665. if (NULL != channel_map)
  2666. {
  2667. GNUNET_CONTAINER_multihashmap_iterate (channel_map,
  2668. &cleanup_channel,
  2669. NULL);
  2670. GNUNET_CONTAINER_multihashmap_destroy (channel_map);
  2671. channel_map = NULL;
  2672. }
  2673. if (NULL != channel_heap)
  2674. {
  2675. GNUNET_CONTAINER_heap_destroy (channel_heap);
  2676. channel_heap = NULL;
  2677. }
  2678. if (NULL != cadet_handle)
  2679. {
  2680. GNUNET_CADET_disconnect (cadet_handle);
  2681. cadet_handle = NULL;
  2682. }
  2683. if (NULL != helper_handle)
  2684. {
  2685. GNUNET_HELPER_stop (helper_handle, GNUNET_NO);
  2686. helper_handle = NULL;
  2687. }
  2688. if (NULL != nc)
  2689. {
  2690. GNUNET_SERVER_notification_context_destroy (nc);
  2691. nc = NULL;
  2692. }
  2693. if (NULL != stats)
  2694. {
  2695. GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
  2696. stats = NULL;
  2697. }
  2698. for (i=0;i<5;i++)
  2699. GNUNET_free_non_null (vpn_argv[i]);
  2700. }
  2701. /**
  2702. * Main function that will be run by the scheduler.
  2703. *
  2704. * @param cls closure
  2705. * @param server the initialized server
  2706. * @param cfg_ configuration
  2707. */
  2708. static void
  2709. run (void *cls,
  2710. struct GNUNET_SERVER_Handle *server,
  2711. const struct GNUNET_CONFIGURATION_Handle *cfg_)
  2712. {
  2713. static const struct GNUNET_SERVER_MessageHandler service_handlers[] = {
  2714. /* callback, cls, type, size */
  2715. { &service_redirect_to_ip, NULL, GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP, 0},
  2716. { &service_redirect_to_service, NULL,
  2717. GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_SERVICE,
  2718. sizeof (struct RedirectToServiceRequestMessage) },
  2719. {NULL, NULL, 0, 0}
  2720. };
  2721. static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = {
  2722. { &receive_udp_back, GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY, 0},
  2723. { &receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN, 0},
  2724. { &receive_icmp_back, GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN, 0},
  2725. {NULL, 0, 0}
  2726. };
  2727. char *ifname;
  2728. char *ipv6addr;
  2729. char *ipv6prefix_s;
  2730. char *ipv4addr;
  2731. char *ipv4mask;
  2732. struct in_addr v4;
  2733. struct in6_addr v6;
  2734. char *binary;
  2735. binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-vpn");
  2736. if (GNUNET_YES !=
  2737. GNUNET_OS_check_helper_binary (binary,
  2738. GNUNET_YES,
  2739. "-d gnunet-vpn - - 169.1.3.3.7 255.255.255.0")) //ipv4 only please!
  2740. {
  2741. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  2742. "`%s' is not SUID, refusing to run.\n",
  2743. "gnunet-helper-vpn");
  2744. GNUNET_free (binary);
  2745. global_ret = 1;
  2746. /* we won't "really" exit here, as the 'service' is still running;
  2747. however, as no handlers are registered, the service won't do
  2748. anything either */
  2749. return;
  2750. }
  2751. GNUNET_free (binary);
  2752. cfg = cfg_;
  2753. stats = GNUNET_STATISTICS_create ("vpn", cfg);
  2754. if (GNUNET_OK !=
  2755. GNUNET_CONFIGURATION_get_value_number (cfg, "VPN", "MAX_MAPPING",
  2756. &max_destination_mappings))
  2757. max_destination_mappings = 200;
  2758. if (GNUNET_OK !=
  2759. GNUNET_CONFIGURATION_get_value_number (cfg, "VPN", "MAX_TUNNELS",
  2760. &max_channel_mappings))
  2761. max_channel_mappings = 200;
  2762. destination_map = GNUNET_CONTAINER_multihashmap_create (max_destination_mappings * 2, GNUNET_NO);
  2763. destination_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
  2764. channel_map = GNUNET_CONTAINER_multihashmap_create (max_channel_mappings * 2, GNUNET_NO);
  2765. channel_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
  2766. vpn_argv[0] = GNUNET_strdup ("vpn-gnunet");
  2767. if (GNUNET_SYSERR ==
  2768. GNUNET_CONFIGURATION_get_value_string (cfg, "VPN", "IFNAME", &ifname))
  2769. {
  2770. GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "VPN", "IFNAME");
  2771. GNUNET_SCHEDULER_shutdown ();
  2772. return;
  2773. }
  2774. vpn_argv[1] = ifname;
  2775. ipv6addr = NULL;
  2776. if (GNUNET_OK == GNUNET_NETWORK_test_pf (PF_INET6))
  2777. {
  2778. if ( (GNUNET_SYSERR ==
  2779. GNUNET_CONFIGURATION_get_value_string (cfg, "VPN", "IPV6ADDR",
  2780. &ipv6addr) ||
  2781. (1 != inet_pton (AF_INET6, ipv6addr, &v6))) )
  2782. {
  2783. GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "VPN", "IPV6ADDR",
  2784. _("Must specify valid IPv6 address"));
  2785. GNUNET_SCHEDULER_shutdown ();
  2786. GNUNET_free_non_null (ipv6addr);
  2787. return;
  2788. }
  2789. vpn_argv[2] = ipv6addr;
  2790. ipv6prefix_s = NULL;
  2791. if (GNUNET_SYSERR ==
  2792. GNUNET_CONFIGURATION_get_value_string (cfg, "VPN", "IPV6PREFIX",
  2793. &ipv6prefix_s))
  2794. {
  2795. GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "VPN", "IPV6PREFIX");
  2796. GNUNET_SCHEDULER_shutdown ();
  2797. GNUNET_free_non_null (ipv6prefix_s);
  2798. return;
  2799. }
  2800. vpn_argv[3] = ipv6prefix_s;
  2801. if ( (GNUNET_OK !=
  2802. GNUNET_CONFIGURATION_get_value_number (cfg, "VPN",
  2803. "IPV6PREFIX",
  2804. &ipv6prefix)) ||
  2805. (ipv6prefix >= 127) )
  2806. {
  2807. GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "VPN", "IPV4MASK",
  2808. _("Must specify valid IPv6 mask"));
  2809. GNUNET_SCHEDULER_shutdown ();
  2810. return;
  2811. }
  2812. }
  2813. else
  2814. {
  2815. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  2816. _("IPv6 support disabled as this system does not support IPv6\n"));
  2817. vpn_argv[2] = GNUNET_strdup ("-");
  2818. vpn_argv[3] = GNUNET_strdup ("-");
  2819. }
  2820. if (GNUNET_OK == GNUNET_NETWORK_test_pf (PF_INET))
  2821. {
  2822. ipv4addr = NULL;
  2823. if ( (GNUNET_SYSERR ==
  2824. GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4ADDR",
  2825. &ipv4addr) ||
  2826. (1 != inet_pton (AF_INET, ipv4addr, &v4))) )
  2827. {
  2828. GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "VPN", "IPV4ADDR",
  2829. _("Must specify valid IPv4 address"));
  2830. GNUNET_SCHEDULER_shutdown ();
  2831. GNUNET_free_non_null (ipv4addr);
  2832. return;
  2833. }
  2834. vpn_argv[4] = ipv4addr;
  2835. ipv4mask = NULL;
  2836. if ( (GNUNET_SYSERR ==
  2837. GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4MASK",
  2838. &ipv4mask) ||
  2839. (1 != inet_pton (AF_INET, ipv4mask, &v4))) )
  2840. {
  2841. GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "VPN", "IPV4MASK",
  2842. _("Must specify valid IPv4 mask"));
  2843. GNUNET_SCHEDULER_shutdown ();
  2844. GNUNET_free_non_null (ipv4mask);
  2845. return;
  2846. }
  2847. vpn_argv[5] = ipv4mask;
  2848. }
  2849. else
  2850. {
  2851. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  2852. _("IPv4 support disabled as this system does not support IPv4\n"));
  2853. vpn_argv[4] = GNUNET_strdup ("-");
  2854. vpn_argv[5] = GNUNET_strdup ("-");
  2855. }
  2856. vpn_argv[6] = NULL;
  2857. cadet_handle =
  2858. GNUNET_CADET_connect (cfg_, NULL,
  2859. NULL,
  2860. &channel_cleaner,
  2861. cadet_handlers,
  2862. NULL);
  2863. helper_handle = GNUNET_HELPER_start (GNUNET_NO,
  2864. "gnunet-helper-vpn", vpn_argv,
  2865. &message_token, NULL, NULL);
  2866. nc = GNUNET_SERVER_notification_context_create (server, 1);
  2867. GNUNET_SERVER_add_handlers (server, service_handlers);
  2868. GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls);
  2869. }
  2870. /**
  2871. * The main function of the VPN service.
  2872. *
  2873. * @param argc number of arguments from the command line
  2874. * @param argv command line arguments
  2875. * @return 0 ok, 1 on error
  2876. */
  2877. int
  2878. main (int argc, char *const *argv)
  2879. {
  2880. return (GNUNET_OK ==
  2881. GNUNET_SERVICE_run (argc, argv, "vpn",
  2882. GNUNET_SERVICE_OPTION_NONE,
  2883. &run, NULL)) ? global_ret : 1;
  2884. }
  2885. /* end of gnunet-service-vpn.c */