gnunet-service-vpn.c 96 KB

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