service.c 68 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2016 GNUnet e.V.
  4. GNUnet is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published
  6. by the Free Software Foundation; either version 3, or (at your
  7. option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNUnet; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  15. Boston, MA 02110-1301, USA.
  16. */
  17. /**
  18. * @file util/service_new.c
  19. * @brief functions related to starting services (redesign)
  20. * @author Christian Grothoff
  21. * @author Florian Dold
  22. */
  23. #include "platform.h"
  24. #include "gnunet_util_lib.h"
  25. #include "gnunet_protocols.h"
  26. #include "gnunet_constants.h"
  27. #include "gnunet_resolver_service.h"
  28. #include "speedup.h"
  29. #if HAVE_MALLINFO
  30. #include <malloc.h>
  31. #include "gauger.h"
  32. #endif
  33. #define LOG(kind,...) GNUNET_log_from (kind, "util-service", __VA_ARGS__)
  34. #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-service", syscall)
  35. #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-service", syscall, filename)
  36. /**
  37. * Information the service tracks per listen operation.
  38. */
  39. struct ServiceListenContext
  40. {
  41. /**
  42. * Kept in a DLL.
  43. */
  44. struct ServiceListenContext *next;
  45. /**
  46. * Kept in a DLL.
  47. */
  48. struct ServiceListenContext *prev;
  49. /**
  50. * Service this listen context belongs to.
  51. */
  52. struct GNUNET_SERVICE_Handle *sh;
  53. /**
  54. * Socket we are listening on.
  55. */
  56. struct GNUNET_NETWORK_Handle *listen_socket;
  57. /**
  58. * Task scheduled to do the listening.
  59. */
  60. struct GNUNET_SCHEDULER_Task *listen_task;
  61. };
  62. /**
  63. * Handle to a service.
  64. */
  65. struct GNUNET_SERVICE_Handle
  66. {
  67. /**
  68. * Our configuration.
  69. */
  70. const struct GNUNET_CONFIGURATION_Handle *cfg;
  71. /**
  72. * Name of our service.
  73. */
  74. const char *service_name;
  75. /**
  76. * Main service-specific task to run.
  77. */
  78. GNUNET_SERVICE_InitCallback service_init_cb;
  79. /**
  80. * Function to call when clients connect.
  81. */
  82. GNUNET_SERVICE_ConnectHandler connect_cb;
  83. /**
  84. * Function to call when clients disconnect / are disconnected.
  85. */
  86. GNUNET_SERVICE_DisconnectHandler disconnect_cb;
  87. /**
  88. * Closure for @e service_init_cb, @e connect_cb, @e disconnect_cb.
  89. */
  90. void *cb_cls;
  91. /**
  92. * DLL of listen sockets used to accept new connections.
  93. */
  94. struct ServiceListenContext *slc_head;
  95. /**
  96. * DLL of listen sockets used to accept new connections.
  97. */
  98. struct ServiceListenContext *slc_tail;
  99. /**
  100. * Our clients, kept in a DLL.
  101. */
  102. struct GNUNET_SERVICE_Client *clients_head;
  103. /**
  104. * Our clients, kept in a DLL.
  105. */
  106. struct GNUNET_SERVICE_Client *clients_tail;
  107. /**
  108. * Message handlers to use for all clients.
  109. */
  110. struct GNUNET_MQ_MessageHandler *handlers;
  111. /**
  112. * Closure for @e task.
  113. */
  114. void *task_cls;
  115. /**
  116. * IPv4 addresses that are not allowed to connect.
  117. */
  118. struct GNUNET_STRINGS_IPv4NetworkPolicy *v4_denied;
  119. /**
  120. * IPv6 addresses that are not allowed to connect.
  121. */
  122. struct GNUNET_STRINGS_IPv6NetworkPolicy *v6_denied;
  123. /**
  124. * IPv4 addresses that are allowed to connect (if not
  125. * set, all are allowed).
  126. */
  127. struct GNUNET_STRINGS_IPv4NetworkPolicy *v4_allowed;
  128. /**
  129. * IPv6 addresses that are allowed to connect (if not
  130. * set, all are allowed).
  131. */
  132. struct GNUNET_STRINGS_IPv6NetworkPolicy *v6_allowed;
  133. /**
  134. * Do we require a matching UID for UNIX domain socket connections?
  135. * #GNUNET_NO means that the UID does not have to match (however,
  136. * @e match_gid may still impose other access control checks).
  137. */
  138. int match_uid;
  139. /**
  140. * Do we require a matching GID for UNIX domain socket connections?
  141. * Ignored if @e match_uid is #GNUNET_YES. Note that this is about
  142. * checking that the client's UID is in our group OR that the
  143. * client's GID is our GID. If both "match_gid" and @e match_uid are
  144. * #GNUNET_NO, all users on the local system have access.
  145. */
  146. int match_gid;
  147. /**
  148. * Set to #GNUNET_YES if we got a shutdown signal and terminate
  149. * the service if #have_non_monitor_clients() returns #GNUNET_YES.
  150. */
  151. int got_shutdown;
  152. /**
  153. * Our options.
  154. */
  155. enum GNUNET_SERVICE_Options options;
  156. /**
  157. * If we are daemonizing, this FD is set to the
  158. * pipe to the parent. Send '.' if we started
  159. * ok, '!' if not. -1 if we are not daemonizing.
  160. */
  161. int ready_confirm_fd;
  162. /**
  163. * Overall success/failure of the service start.
  164. */
  165. int ret;
  166. /**
  167. * If #GNUNET_YES, consider unknown message types an error where the
  168. * client is disconnected.
  169. */
  170. int require_found;
  171. };
  172. /**
  173. * Handle to a client that is connected to a service.
  174. */
  175. struct GNUNET_SERVICE_Client
  176. {
  177. /**
  178. * Kept in a DLL.
  179. */
  180. struct GNUNET_SERVICE_Client *next;
  181. /**
  182. * Kept in a DLL.
  183. */
  184. struct GNUNET_SERVICE_Client *prev;
  185. /**
  186. * Service that this client belongs to.
  187. */
  188. struct GNUNET_SERVICE_Handle *sh;
  189. /**
  190. * Socket of this client.
  191. */
  192. struct GNUNET_NETWORK_Handle *sock;
  193. /**
  194. * Message queue for the client.
  195. */
  196. struct GNUNET_MQ_Handle *mq;
  197. /**
  198. * Tokenizer we use for processing incoming data.
  199. */
  200. struct GNUNET_MessageStreamTokenizer *mst;
  201. /**
  202. * Task that warns about missing calls to
  203. * #GNUNET_SERVICE_client_continue().
  204. */
  205. struct GNUNET_SCHEDULER_Task *warn_task;
  206. /**
  207. * Task run to finish dropping the client after the stack has
  208. * properly unwound.
  209. */
  210. struct GNUNET_SCHEDULER_Task *drop_task;
  211. /**
  212. * Task that receives data from the client to
  213. * pass it to the handlers.
  214. */
  215. struct GNUNET_SCHEDULER_Task *recv_task;
  216. /**
  217. * Task that transmit data to the client.
  218. */
  219. struct GNUNET_SCHEDULER_Task *send_task;
  220. /**
  221. * Pointer to the message to be transmitted by @e send_task.
  222. */
  223. const struct GNUNET_MessageHeader *msg;
  224. /**
  225. * User context value, value returned from
  226. * the connect callback.
  227. */
  228. void *user_context;
  229. /**
  230. * Time when we last gave a message from this client
  231. * to the application.
  232. */
  233. struct GNUNET_TIME_Absolute warn_start;
  234. /**
  235. * Current position in @e msg at which we are transmitting.
  236. */
  237. size_t msg_pos;
  238. /**
  239. * Persist the file handle for this client no matter what happens,
  240. * force the OS to close once the process actually dies. Should only
  241. * be used in special cases!
  242. */
  243. int persist;
  244. /**
  245. * Is this client a 'monitor' client that should not be counted
  246. * when deciding on destroying the server during soft shutdown?
  247. * (see also #GNUNET_SERVICE_start)
  248. */
  249. int is_monitor;
  250. /**
  251. * Are we waiting for the application to call #GNUNET_SERVICE_client_continue()?
  252. */
  253. int needs_continue;
  254. /**
  255. * Type of last message processed (for warn_no_receive_done).
  256. */
  257. uint16_t warn_type;
  258. };
  259. /**
  260. * Check if any of the clients we have left are unrelated to
  261. * monitoring.
  262. *
  263. * @param sh service to check clients for
  264. * @return #GNUNET_YES if we have non-monitoring clients left
  265. */
  266. static int
  267. have_non_monitor_clients (struct GNUNET_SERVICE_Handle *sh)
  268. {
  269. struct GNUNET_SERVICE_Client *client;
  270. for (client = sh->clients_head;NULL != client; client = client->next)
  271. {
  272. if (client->is_monitor)
  273. continue;
  274. return GNUNET_YES;
  275. }
  276. return GNUNET_NO;
  277. }
  278. /**
  279. * Shutdown task triggered when a service should be terminated.
  280. * This considers active clients and the service options to see
  281. * how this specific service is to be terminated, and depending
  282. * on this proceeds with the shutdown logic.
  283. *
  284. * @param cls our `struct GNUNET_SERVICE_Handle`
  285. */
  286. static void
  287. service_shutdown (void *cls)
  288. {
  289. struct GNUNET_SERVICE_Handle *sh = cls;
  290. switch (sh->options)
  291. {
  292. case GNUNET_SERVICE_OPTION_NONE:
  293. GNUNET_SERVICE_shutdown (sh);
  294. break;
  295. case GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN:
  296. /* This task should never be run if we are using
  297. the manual shutdown. */
  298. GNUNET_assert (0);
  299. break;
  300. case GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN:
  301. sh->got_shutdown = GNUNET_YES;
  302. GNUNET_SERVICE_suspend (sh);
  303. if (GNUNET_NO == have_non_monitor_clients (sh))
  304. GNUNET_SERVICE_shutdown (sh);
  305. break;
  306. }
  307. }
  308. /**
  309. * First task run by any service. Initializes our shutdown task,
  310. * starts the listening operation on our listen sockets and launches
  311. * the custom logic of the application service.
  312. *
  313. * @param cls our `struct GNUNET_SERVICE_Handle`
  314. */
  315. static void
  316. service_main (void *cls)
  317. {
  318. struct GNUNET_SERVICE_Handle *sh = cls;
  319. if (GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN != sh->options)
  320. GNUNET_SCHEDULER_add_shutdown (&service_shutdown,
  321. sh);
  322. GNUNET_SERVICE_resume (sh);
  323. if (-1 != sh->ready_confirm_fd)
  324. {
  325. GNUNET_break (1 == WRITE (sh->ready_confirm_fd, ".", 1));
  326. GNUNET_break (0 == CLOSE (sh->ready_confirm_fd));
  327. sh->ready_confirm_fd = -1;
  328. }
  329. if (NULL != sh->service_init_cb)
  330. sh->service_init_cb (sh->cb_cls,
  331. sh->cfg,
  332. sh);
  333. }
  334. /**
  335. * Parse an IPv4 access control list.
  336. *
  337. * @param ret location where to write the ACL (set)
  338. * @param sh service context to use to get the configuration
  339. * @param option name of the ACL option to parse
  340. * @return #GNUNET_SYSERR on parse error, #GNUNET_OK on success (including
  341. * no ACL configured)
  342. */
  343. static int
  344. process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret,
  345. struct GNUNET_SERVICE_Handle *sh,
  346. const char *option)
  347. {
  348. char *opt;
  349. if (! GNUNET_CONFIGURATION_have_value (sh->cfg,
  350. sh->service_name,
  351. option))
  352. {
  353. *ret = NULL;
  354. return GNUNET_OK;
  355. }
  356. GNUNET_break (GNUNET_OK ==
  357. GNUNET_CONFIGURATION_get_value_string (sh->cfg,
  358. sh->service_name,
  359. option,
  360. &opt));
  361. if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy (opt)))
  362. {
  363. LOG (GNUNET_ERROR_TYPE_WARNING,
  364. _("Could not parse IPv4 network specification `%s' for `%s:%s'\n"),
  365. opt,
  366. sh->service_name,
  367. option);
  368. GNUNET_free (opt);
  369. return GNUNET_SYSERR;
  370. }
  371. GNUNET_free (opt);
  372. return GNUNET_OK;
  373. }
  374. /**
  375. * Parse an IPv6 access control list.
  376. *
  377. * @param ret location where to write the ACL (set)
  378. * @param sh service context to use to get the configuration
  379. * @param option name of the ACL option to parse
  380. * @return #GNUNET_SYSERR on parse error, #GNUNET_OK on success (including
  381. * no ACL configured)
  382. */
  383. static int
  384. process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret,
  385. struct GNUNET_SERVICE_Handle *sh,
  386. const char *option)
  387. {
  388. char *opt;
  389. if (! GNUNET_CONFIGURATION_have_value (sh->cfg,
  390. sh->service_name,
  391. option))
  392. {
  393. *ret = NULL;
  394. return GNUNET_OK;
  395. }
  396. GNUNET_break (GNUNET_OK ==
  397. GNUNET_CONFIGURATION_get_value_string (sh->cfg,
  398. sh->service_name,
  399. option,
  400. &opt));
  401. if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy (opt)))
  402. {
  403. LOG (GNUNET_ERROR_TYPE_WARNING,
  404. _("Could not parse IPv6 network specification `%s' for `%s:%s'\n"),
  405. opt,
  406. sh->service_name,
  407. option);
  408. GNUNET_free (opt);
  409. return GNUNET_SYSERR;
  410. }
  411. GNUNET_free (opt);
  412. return GNUNET_OK;
  413. }
  414. /**
  415. * Add the given UNIX domain path as an address to the
  416. * list (as the first entry).
  417. *
  418. * @param saddrs array to update
  419. * @param saddrlens where to store the address length
  420. * @param unixpath path to add
  421. * @param abstract #GNUNET_YES to add an abstract UNIX domain socket. This
  422. * parameter is ignore on systems other than LINUX
  423. */
  424. static void
  425. add_unixpath (struct sockaddr **saddrs,
  426. socklen_t *saddrlens,
  427. const char *unixpath,
  428. int abstract)
  429. {
  430. #ifdef AF_UNIX
  431. struct sockaddr_un *un;
  432. un = GNUNET_new (struct sockaddr_un);
  433. un->sun_family = AF_UNIX;
  434. strncpy (un->sun_path,
  435. unixpath,
  436. sizeof (un->sun_path) - 1);
  437. #ifdef LINUX
  438. if (GNUNET_YES == abstract)
  439. un->sun_path[0] = '\0';
  440. #endif
  441. #if HAVE_SOCKADDR_UN_SUN_LEN
  442. un->sun_len = (u_char) sizeof (struct sockaddr_un);
  443. #endif
  444. *saddrs = (struct sockaddr *) un;
  445. *saddrlens = sizeof (struct sockaddr_un);
  446. #else
  447. /* this function should never be called
  448. * unless AF_UNIX is defined! */
  449. GNUNET_assert (0);
  450. #endif
  451. }
  452. /**
  453. * Get the list of addresses that a server for the given service
  454. * should bind to.
  455. *
  456. * @param service_name name of the service
  457. * @param cfg configuration (which specifies the addresses)
  458. * @param addrs set (call by reference) to an array of pointers to the
  459. * addresses the server should bind to and listen on; the
  460. * array will be NULL-terminated (on success)
  461. * @param addr_lens set (call by reference) to an array of the lengths
  462. * of the respective `struct sockaddr` struct in the @a addrs
  463. * array (on success)
  464. * @return number of addresses found on success,
  465. * #GNUNET_SYSERR if the configuration
  466. * did not specify reasonable finding information or
  467. * if it specified a hostname that could not be resolved;
  468. * #GNUNET_NO if the number of addresses configured is
  469. * zero (in this case, `*addrs` and `*addr_lens` will be
  470. * set to NULL).
  471. */
  472. static int
  473. get_server_addresses (const char *service_name,
  474. const struct GNUNET_CONFIGURATION_Handle *cfg,
  475. struct sockaddr ***addrs,
  476. socklen_t **addr_lens)
  477. {
  478. int disablev6;
  479. struct GNUNET_NETWORK_Handle *desc;
  480. unsigned long long port;
  481. char *unixpath;
  482. struct addrinfo hints;
  483. struct addrinfo *res;
  484. struct addrinfo *pos;
  485. struct addrinfo *next;
  486. unsigned int i;
  487. int resi;
  488. int ret;
  489. int abstract;
  490. struct sockaddr **saddrs;
  491. socklen_t *saddrlens;
  492. char *hostname;
  493. *addrs = NULL;
  494. *addr_lens = NULL;
  495. desc = NULL;
  496. if (GNUNET_CONFIGURATION_have_value (cfg,
  497. service_name,
  498. "DISABLEV6"))
  499. {
  500. if (GNUNET_SYSERR ==
  501. (disablev6 =
  502. GNUNET_CONFIGURATION_get_value_yesno (cfg,
  503. service_name,
  504. "DISABLEV6")))
  505. return GNUNET_SYSERR;
  506. }
  507. else
  508. disablev6 = GNUNET_NO;
  509. if (! disablev6)
  510. {
  511. /* probe IPv6 support */
  512. desc = GNUNET_NETWORK_socket_create (PF_INET6,
  513. SOCK_STREAM,
  514. 0);
  515. if (NULL == desc)
  516. {
  517. if ( (ENOBUFS == errno) ||
  518. (ENOMEM == errno) ||
  519. (ENFILE == errno) ||
  520. (EACCES == errno) )
  521. {
  522. LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
  523. "socket");
  524. return GNUNET_SYSERR;
  525. }
  526. LOG (GNUNET_ERROR_TYPE_INFO,
  527. _("Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
  528. service_name,
  529. STRERROR (errno));
  530. disablev6 = GNUNET_YES;
  531. }
  532. else
  533. {
  534. GNUNET_break (GNUNET_OK ==
  535. GNUNET_NETWORK_socket_close (desc));
  536. desc = NULL;
  537. }
  538. }
  539. port = 0;
  540. if (GNUNET_CONFIGURATION_have_value (cfg,
  541. service_name,
  542. "PORT"))
  543. {
  544. if (GNUNET_OK !=
  545. GNUNET_CONFIGURATION_get_value_number (cfg,
  546. service_name,
  547. "PORT",
  548. &port))
  549. {
  550. LOG (GNUNET_ERROR_TYPE_ERROR,
  551. _("Require valid port number for service `%s' in configuration!\n"),
  552. service_name);
  553. }
  554. if (port > 65535)
  555. {
  556. LOG (GNUNET_ERROR_TYPE_ERROR,
  557. _("Require valid port number for service `%s' in configuration!\n"),
  558. service_name);
  559. return GNUNET_SYSERR;
  560. }
  561. }
  562. if (GNUNET_CONFIGURATION_have_value (cfg,
  563. service_name,
  564. "BINDTO"))
  565. {
  566. GNUNET_break (GNUNET_OK ==
  567. GNUNET_CONFIGURATION_get_value_string (cfg,
  568. service_name,
  569. "BINDTO",
  570. &hostname));
  571. }
  572. else
  573. hostname = NULL;
  574. unixpath = NULL;
  575. abstract = GNUNET_NO;
  576. #ifdef AF_UNIX
  577. if ((GNUNET_YES ==
  578. GNUNET_CONFIGURATION_have_value (cfg,
  579. service_name,
  580. "UNIXPATH")) &&
  581. (GNUNET_OK ==
  582. GNUNET_CONFIGURATION_get_value_filename (cfg,
  583. service_name,
  584. "UNIXPATH",
  585. &unixpath)) &&
  586. (0 < strlen (unixpath)))
  587. {
  588. /* probe UNIX support */
  589. struct sockaddr_un s_un;
  590. if (strlen (unixpath) >= sizeof (s_un.sun_path))
  591. {
  592. LOG (GNUNET_ERROR_TYPE_WARNING,
  593. _("UNIXPATH `%s' too long, maximum length is %llu\n"),
  594. unixpath,
  595. (unsigned long long) sizeof (s_un.sun_path));
  596. unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
  597. LOG (GNUNET_ERROR_TYPE_INFO,
  598. _("Using `%s' instead\n"),
  599. unixpath);
  600. }
  601. #ifdef LINUX
  602. abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg,
  603. "TESTING",
  604. "USE_ABSTRACT_SOCKETS");
  605. if (GNUNET_SYSERR == abstract)
  606. abstract = GNUNET_NO;
  607. #endif
  608. if ( (GNUNET_YES != abstract) &&
  609. (GNUNET_OK !=
  610. GNUNET_DISK_directory_create_for_file (unixpath)) )
  611. GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
  612. "mkdir",
  613. unixpath);
  614. }
  615. if (NULL != unixpath)
  616. {
  617. desc = GNUNET_NETWORK_socket_create (AF_UNIX,
  618. SOCK_STREAM,
  619. 0);
  620. if (NULL == desc)
  621. {
  622. if ((ENOBUFS == errno) ||
  623. (ENOMEM == errno) ||
  624. (ENFILE == errno) ||
  625. (EACCES == errno))
  626. {
  627. LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
  628. "socket");
  629. GNUNET_free_non_null (hostname);
  630. GNUNET_free (unixpath);
  631. return GNUNET_SYSERR;
  632. }
  633. LOG (GNUNET_ERROR_TYPE_INFO,
  634. _("Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
  635. service_name,
  636. STRERROR (errno));
  637. GNUNET_free (unixpath);
  638. unixpath = NULL;
  639. }
  640. else
  641. {
  642. GNUNET_break (GNUNET_OK ==
  643. GNUNET_NETWORK_socket_close (desc));
  644. desc = NULL;
  645. }
  646. }
  647. #endif
  648. if ((0 == port) && (NULL == unixpath))
  649. {
  650. LOG (GNUNET_ERROR_TYPE_ERROR,
  651. _("Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
  652. service_name);
  653. GNUNET_free_non_null (hostname);
  654. return GNUNET_SYSERR;
  655. }
  656. if (0 == port)
  657. {
  658. saddrs = GNUNET_new_array (2,
  659. struct sockaddr *);
  660. saddrlens = GNUNET_new_array (2,
  661. socklen_t);
  662. add_unixpath (saddrs,
  663. saddrlens,
  664. unixpath,
  665. abstract);
  666. GNUNET_free_non_null (unixpath);
  667. GNUNET_free_non_null (hostname);
  668. *addrs = saddrs;
  669. *addr_lens = saddrlens;
  670. return 1;
  671. }
  672. if (NULL != hostname)
  673. {
  674. LOG (GNUNET_ERROR_TYPE_DEBUG,
  675. "Resolving `%s' since that is where `%s' will bind to.\n",
  676. hostname,
  677. service_name);
  678. memset (&hints,
  679. 0,
  680. sizeof (struct addrinfo));
  681. if (disablev6)
  682. hints.ai_family = AF_INET;
  683. hints.ai_protocol = IPPROTO_TCP;
  684. if ((0 != (ret = getaddrinfo (hostname,
  685. NULL,
  686. &hints,
  687. &res))) ||
  688. (NULL == res))
  689. {
  690. LOG (GNUNET_ERROR_TYPE_ERROR,
  691. _("Failed to resolve `%s': %s\n"),
  692. hostname,
  693. gai_strerror (ret));
  694. GNUNET_free (hostname);
  695. GNUNET_free_non_null (unixpath);
  696. return GNUNET_SYSERR;
  697. }
  698. next = res;
  699. i = 0;
  700. while (NULL != (pos = next))
  701. {
  702. next = pos->ai_next;
  703. if ( (disablev6) &&
  704. (pos->ai_family == AF_INET6) )
  705. continue;
  706. i++;
  707. }
  708. if (0 == i)
  709. {
  710. LOG (GNUNET_ERROR_TYPE_ERROR,
  711. _("Failed to find %saddress for `%s'.\n"),
  712. disablev6 ? "IPv4 " : "",
  713. hostname);
  714. freeaddrinfo (res);
  715. GNUNET_free (hostname);
  716. GNUNET_free_non_null (unixpath);
  717. return GNUNET_SYSERR;
  718. }
  719. resi = i;
  720. if (NULL != unixpath)
  721. resi++;
  722. saddrs = GNUNET_new_array (resi + 1,
  723. struct sockaddr *);
  724. saddrlens = GNUNET_new_array (resi + 1,
  725. socklen_t);
  726. i = 0;
  727. if (NULL != unixpath)
  728. {
  729. add_unixpath (saddrs,
  730. saddrlens,
  731. unixpath,
  732. abstract);
  733. i++;
  734. }
  735. next = res;
  736. while (NULL != (pos = next))
  737. {
  738. next = pos->ai_next;
  739. if ( (disablev6) &&
  740. (AF_INET6 == pos->ai_family) )
  741. continue;
  742. if ( (IPPROTO_TCP != pos->ai_protocol) &&
  743. (0 != pos->ai_protocol) )
  744. continue; /* not TCP */
  745. if ( (SOCK_STREAM != pos->ai_socktype) &&
  746. (0 != pos->ai_socktype) )
  747. continue; /* huh? */
  748. LOG (GNUNET_ERROR_TYPE_DEBUG,
  749. "Service `%s' will bind to `%s'\n",
  750. service_name,
  751. GNUNET_a2s (pos->ai_addr,
  752. pos->ai_addrlen));
  753. if (AF_INET == pos->ai_family)
  754. {
  755. GNUNET_assert (sizeof (struct sockaddr_in) == pos->ai_addrlen);
  756. saddrlens[i] = pos->ai_addrlen;
  757. saddrs[i] = GNUNET_malloc (saddrlens[i]);
  758. GNUNET_memcpy (saddrs[i],
  759. pos->ai_addr,
  760. saddrlens[i]);
  761. ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
  762. }
  763. else
  764. {
  765. GNUNET_assert (AF_INET6 == pos->ai_family);
  766. GNUNET_assert (sizeof (struct sockaddr_in6) == pos->ai_addrlen);
  767. saddrlens[i] = pos->ai_addrlen;
  768. saddrs[i] = GNUNET_malloc (saddrlens[i]);
  769. GNUNET_memcpy (saddrs[i],
  770. pos->ai_addr,
  771. saddrlens[i]);
  772. ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
  773. }
  774. i++;
  775. }
  776. GNUNET_free (hostname);
  777. freeaddrinfo (res);
  778. resi = i;
  779. }
  780. else
  781. {
  782. /* will bind against everything, just set port */
  783. if (disablev6)
  784. {
  785. /* V4-only */
  786. resi = 1;
  787. if (NULL != unixpath)
  788. resi++;
  789. i = 0;
  790. saddrs = GNUNET_new_array (resi + 1,
  791. struct sockaddr *);
  792. saddrlens = GNUNET_new_array (resi + 1,
  793. socklen_t);
  794. if (NULL != unixpath)
  795. {
  796. add_unixpath (saddrs,
  797. saddrlens,
  798. unixpath,
  799. abstract);
  800. i++;
  801. }
  802. saddrlens[i] = sizeof (struct sockaddr_in);
  803. saddrs[i] = GNUNET_malloc (saddrlens[i]);
  804. #if HAVE_SOCKADDR_IN_SIN_LEN
  805. ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i];
  806. #endif
  807. ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
  808. ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
  809. }
  810. else
  811. {
  812. /* dual stack */
  813. resi = 2;
  814. if (NULL != unixpath)
  815. resi++;
  816. saddrs = GNUNET_new_array (resi + 1,
  817. struct sockaddr *);
  818. saddrlens = GNUNET_new_array (resi + 1,
  819. socklen_t);
  820. i = 0;
  821. if (NULL != unixpath)
  822. {
  823. add_unixpath (saddrs,
  824. saddrlens,
  825. unixpath,
  826. abstract);
  827. i++;
  828. }
  829. saddrlens[i] = sizeof (struct sockaddr_in6);
  830. saddrs[i] = GNUNET_malloc (saddrlens[i]);
  831. #if HAVE_SOCKADDR_IN_SIN_LEN
  832. ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0];
  833. #endif
  834. ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6;
  835. ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
  836. i++;
  837. saddrlens[i] = sizeof (struct sockaddr_in);
  838. saddrs[i] = GNUNET_malloc (saddrlens[i]);
  839. #if HAVE_SOCKADDR_IN_SIN_LEN
  840. ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1];
  841. #endif
  842. ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
  843. ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
  844. }
  845. }
  846. GNUNET_free_non_null (unixpath);
  847. *addrs = saddrs;
  848. *addr_lens = saddrlens;
  849. return resi;
  850. }
  851. #ifdef MINGW
  852. /**
  853. * Read listen sockets from the parent process (ARM).
  854. *
  855. * @param sh service context to initialize
  856. * @return NULL-terminated array of sockets on success,
  857. * NULL if not ok (must bind yourself)
  858. */
  859. static struct GNUNET_NETWORK_Handle **
  860. receive_sockets_from_parent (struct GNUNET_SERVICE_Handle *sh)
  861. {
  862. static struct GNUNET_NETWORK_Handle **lsocks;
  863. const char *env_buf;
  864. int fail;
  865. uint64_t count;
  866. uint64_t i;
  867. HANDLE lsocks_pipe;
  868. env_buf = getenv ("GNUNET_OS_READ_LSOCKS");
  869. if ( (NULL == env_buf) ||
  870. (strlen (env_buf) <= 0) )
  871. return NULL;
  872. /* Using W32 API directly here, because this pipe will
  873. * never be used outside of this function, and it's just too much of a bother
  874. * to create a GNUnet API that boxes a HANDLE (the way it is done with socks)
  875. */
  876. lsocks_pipe = (HANDLE) strtoul (env_buf,
  877. NULL,
  878. 10);
  879. if ( (0 == lsocks_pipe) ||
  880. (INVALID_HANDLE_VALUE == lsocks_pipe))
  881. return NULL;
  882. fail = 1;
  883. do
  884. {
  885. int ret;
  886. int fail2;
  887. DWORD rd;
  888. ret = ReadFile (lsocks_pipe,
  889. &count,
  890. sizeof (count),
  891. &rd,
  892. NULL);
  893. if ( (0 == ret) ||
  894. (sizeof (count) != rd) ||
  895. (0 == count) )
  896. break;
  897. lsocks = GNUNET_new_array (count + 1,
  898. struct GNUNET_NETWORK_Handle *);
  899. fail2 = 1;
  900. for (i = 0; i < count; i++)
  901. {
  902. WSAPROTOCOL_INFOA pi;
  903. uint64_t size;
  904. SOCKET s;
  905. ret = ReadFile (lsocks_pipe,
  906. &size,
  907. sizeof (size),
  908. &rd,
  909. NULL);
  910. if ( (0 == ret) ||
  911. (sizeof (size) != rd) ||
  912. (sizeof (pi) != size) )
  913. break;
  914. ret = ReadFile (lsocks_pipe,
  915. &pi,
  916. sizeof (pi),
  917. &rd,
  918. NULL);
  919. if ( (0 == ret) ||
  920. (sizeof (pi) != rd))
  921. break;
  922. s = WSASocketA (pi.iAddressFamily,
  923. pi.iSocketType,
  924. pi.iProtocol,
  925. &pi,
  926. 0,
  927. WSA_FLAG_OVERLAPPED);
  928. lsocks[i] = GNUNET_NETWORK_socket_box_native (s);
  929. if (NULL == lsocks[i])
  930. break;
  931. else if (i == count - 1)
  932. fail2 = 0;
  933. }
  934. if (fail2)
  935. break;
  936. lsocks[count] = NULL;
  937. fail = 0;
  938. }
  939. while (fail);
  940. CloseHandle (lsocks_pipe);
  941. if (fail)
  942. {
  943. LOG (GNUNET_ERROR_TYPE_ERROR,
  944. _("Could not access a pre-bound socket, will try to bind myself\n"));
  945. for (i = 0; (i < count) && (NULL != lsocks[i]); i++)
  946. GNUNET_break (GNUNET_OK ==
  947. GNUNET_NETWORK_socket_close (lsocks[i]));
  948. GNUNET_free (lsocks);
  949. return NULL;
  950. }
  951. return lsocks;
  952. }
  953. #endif
  954. /**
  955. * Create and initialize a listen socket for the server.
  956. *
  957. * @param server_addr address to listen on
  958. * @param socklen length of @a server_addr
  959. * @return NULL on error, otherwise the listen socket
  960. */
  961. static struct GNUNET_NETWORK_Handle *
  962. open_listen_socket (const struct sockaddr *server_addr,
  963. socklen_t socklen)
  964. {
  965. struct GNUNET_NETWORK_Handle *sock;
  966. uint16_t port;
  967. int eno;
  968. switch (server_addr->sa_family)
  969. {
  970. case AF_INET:
  971. port = ntohs (((const struct sockaddr_in *) server_addr)->sin_port);
  972. break;
  973. case AF_INET6:
  974. port = ntohs (((const struct sockaddr_in6 *) server_addr)->sin6_port);
  975. break;
  976. case AF_UNIX:
  977. port = 0;
  978. break;
  979. default:
  980. GNUNET_break (0);
  981. port = 0;
  982. break;
  983. }
  984. sock = GNUNET_NETWORK_socket_create (server_addr->sa_family,
  985. SOCK_STREAM,
  986. 0);
  987. if (NULL == sock)
  988. {
  989. LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
  990. "socket");
  991. errno = 0;
  992. return NULL;
  993. }
  994. /* bind the socket */
  995. if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock,
  996. server_addr,
  997. socklen))
  998. {
  999. eno = errno;
  1000. if (EADDRINUSE != errno)
  1001. {
  1002. /* we don't log 'EADDRINUSE' here since an IPv4 bind may
  1003. * fail if we already took the port on IPv6; if both IPv4 and
  1004. * IPv6 binds fail, then our caller will log using the
  1005. * errno preserved in 'eno' */
  1006. LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
  1007. "bind");
  1008. if (0 != port)
  1009. LOG (GNUNET_ERROR_TYPE_ERROR,
  1010. _("`%s' failed for port %d (%s).\n"),
  1011. "bind",
  1012. port,
  1013. (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
  1014. eno = 0;
  1015. }
  1016. else
  1017. {
  1018. if (0 != port)
  1019. LOG (GNUNET_ERROR_TYPE_WARNING,
  1020. _("`%s' failed for port %d (%s): address already in use\n"),
  1021. "bind", port,
  1022. (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
  1023. else if (AF_UNIX == server_addr->sa_family)
  1024. {
  1025. LOG (GNUNET_ERROR_TYPE_WARNING,
  1026. _("`%s' failed for `%s': address already in use\n"),
  1027. "bind",
  1028. GNUNET_a2s (server_addr, socklen));
  1029. }
  1030. }
  1031. GNUNET_break (GNUNET_OK ==
  1032. GNUNET_NETWORK_socket_close (sock));
  1033. errno = eno;
  1034. return NULL;
  1035. }
  1036. if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock,
  1037. 5))
  1038. {
  1039. LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
  1040. "listen");
  1041. GNUNET_break (GNUNET_OK ==
  1042. GNUNET_NETWORK_socket_close (sock));
  1043. errno = 0;
  1044. return NULL;
  1045. }
  1046. if (0 != port)
  1047. LOG (GNUNET_ERROR_TYPE_DEBUG,
  1048. "Server starts to listen on port %u.\n",
  1049. port);
  1050. return sock;
  1051. }
  1052. /**
  1053. * Setup service handle
  1054. *
  1055. * Configuration may specify:
  1056. * - PORT (where to bind to for TCP)
  1057. * - UNIXPATH (where to bind to for UNIX domain sockets)
  1058. * - DISABLEV6 (disable support for IPv6, otherwise we use dual-stack)
  1059. * - BINDTO (hostname or IP address to bind to, otherwise we take everything)
  1060. * - ACCEPT_FROM (only allow connections from specified IPv4 subnets)
  1061. * - ACCEPT_FROM6 (only allow connections from specified IPv6 subnets)
  1062. * - REJECT_FROM (disallow allow connections from specified IPv4 subnets)
  1063. * - REJECT_FROM6 (disallow allow connections from specified IPv6 subnets)
  1064. *
  1065. * @param sh service context to initialize
  1066. * @return #GNUNET_OK if configuration succeeded
  1067. */
  1068. static int
  1069. setup_service (struct GNUNET_SERVICE_Handle *sh)
  1070. {
  1071. int tolerant;
  1072. struct GNUNET_NETWORK_Handle **lsocks;
  1073. #ifndef MINGW
  1074. const char *nfds;
  1075. unsigned int cnt;
  1076. int flags;
  1077. #endif
  1078. if (GNUNET_CONFIGURATION_have_value
  1079. (sh->cfg,
  1080. sh->service_name,
  1081. "TOLERANT"))
  1082. {
  1083. if (GNUNET_SYSERR ==
  1084. (tolerant =
  1085. GNUNET_CONFIGURATION_get_value_yesno (sh->cfg,
  1086. sh->service_name,
  1087. "TOLERANT")))
  1088. {
  1089. LOG (GNUNET_ERROR_TYPE_ERROR,
  1090. _("Specified value for `%s' of service `%s' is invalid\n"),
  1091. "TOLERANT",
  1092. sh->service_name);
  1093. return GNUNET_SYSERR;
  1094. }
  1095. }
  1096. else
  1097. tolerant = GNUNET_NO;
  1098. lsocks = NULL;
  1099. #ifndef MINGW
  1100. errno = 0;
  1101. if ( (NULL != (nfds = getenv ("LISTEN_FDS"))) &&
  1102. (1 == SSCANF (nfds,
  1103. "%u",
  1104. &cnt)) &&
  1105. (cnt > 0) &&
  1106. (cnt < FD_SETSIZE) &&
  1107. (cnt + 4 < FD_SETSIZE) )
  1108. {
  1109. lsocks = GNUNET_new_array (cnt + 1,
  1110. struct GNUNET_NETWORK_Handle *);
  1111. while (0 < cnt--)
  1112. {
  1113. flags = fcntl (3 + cnt,
  1114. F_GETFD);
  1115. if ( (flags < 0) ||
  1116. (0 != (flags & FD_CLOEXEC)) ||
  1117. (NULL ==
  1118. (lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt))))
  1119. {
  1120. LOG (GNUNET_ERROR_TYPE_ERROR,
  1121. _("Could not access pre-bound socket %u, will try to bind myself\n"),
  1122. (unsigned int) 3 + cnt);
  1123. cnt++;
  1124. while (NULL != lsocks[cnt])
  1125. GNUNET_break (GNUNET_OK ==
  1126. GNUNET_NETWORK_socket_close (lsocks[cnt++]));
  1127. GNUNET_free (lsocks);
  1128. lsocks = NULL;
  1129. break;
  1130. }
  1131. }
  1132. unsetenv ("LISTEN_FDS");
  1133. }
  1134. #else
  1135. if (NULL != getenv ("GNUNET_OS_READ_LSOCKS"))
  1136. {
  1137. lsocks = receive_sockets_from_parent (sh);
  1138. putenv ("GNUNET_OS_READ_LSOCKS=");
  1139. }
  1140. #endif
  1141. if (NULL != lsocks)
  1142. {
  1143. /* listen only on inherited sockets if we have any */
  1144. struct GNUNET_NETWORK_Handle **ls;
  1145. for (ls = lsocks; NULL != *ls; ls++)
  1146. {
  1147. struct ServiceListenContext *slc;
  1148. slc = GNUNET_new (struct ServiceListenContext);
  1149. slc->sh = sh;
  1150. slc->listen_socket = *ls;
  1151. GNUNET_CONTAINER_DLL_insert (sh->slc_head,
  1152. sh->slc_tail,
  1153. slc);
  1154. }
  1155. GNUNET_free (lsocks);
  1156. }
  1157. else
  1158. {
  1159. struct sockaddr **addrs;
  1160. socklen_t *addrlens;
  1161. int num;
  1162. num = get_server_addresses (sh->service_name,
  1163. sh->cfg,
  1164. &addrs,
  1165. &addrlens);
  1166. if (GNUNET_SYSERR == num)
  1167. return GNUNET_SYSERR;
  1168. for (int i = 0; i < num; i++)
  1169. {
  1170. struct ServiceListenContext *slc;
  1171. slc = GNUNET_new (struct ServiceListenContext);
  1172. slc->sh = sh;
  1173. slc->listen_socket = open_listen_socket (addrs[i],
  1174. addrlens[i]);
  1175. if (NULL == slc->listen_socket)
  1176. {
  1177. GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
  1178. "bind");
  1179. GNUNET_free (addrs[i++]);
  1180. GNUNET_free (slc);
  1181. continue;
  1182. }
  1183. GNUNET_free (addrs[i++]);
  1184. GNUNET_CONTAINER_DLL_insert (sh->slc_head,
  1185. sh->slc_tail,
  1186. slc);
  1187. }
  1188. GNUNET_free_non_null (addrlens);
  1189. GNUNET_free_non_null (addrs);
  1190. if ( (0 != num) &&
  1191. (NULL == sh->slc_head) )
  1192. {
  1193. /* All attempts to bind failed, hard failure */
  1194. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  1195. _("Could not bind to any of the ports I was supposed to, refusing to run!\n"));
  1196. return GNUNET_SYSERR;
  1197. }
  1198. }
  1199. sh->require_found = tolerant ? GNUNET_NO : GNUNET_YES;
  1200. sh->match_uid
  1201. = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg,
  1202. sh->service_name,
  1203. "UNIX_MATCH_UID");
  1204. sh->match_gid
  1205. = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg,
  1206. sh->service_name,
  1207. "UNIX_MATCH_GID");
  1208. process_acl4 (&sh->v4_denied,
  1209. sh,
  1210. "REJECT_FROM");
  1211. process_acl4 (&sh->v4_allowed,
  1212. sh,
  1213. "ACCEPT_FROM");
  1214. process_acl6 (&sh->v6_denied,
  1215. sh,
  1216. "REJECT_FROM6");
  1217. process_acl6 (&sh->v6_allowed,
  1218. sh,
  1219. "ACCEPT_FROM6");
  1220. return GNUNET_OK;
  1221. }
  1222. /**
  1223. * Get the name of the user that'll be used
  1224. * to provide the service.
  1225. *
  1226. * @param sh service context
  1227. * @return value of the 'USERNAME' option
  1228. */
  1229. static char *
  1230. get_user_name (struct GNUNET_SERVICE_Handle *sh)
  1231. {
  1232. char *un;
  1233. if (GNUNET_OK !=
  1234. GNUNET_CONFIGURATION_get_value_filename (sh->cfg,
  1235. sh->service_name,
  1236. "USERNAME",
  1237. &un))
  1238. return NULL;
  1239. return un;
  1240. }
  1241. /**
  1242. * Set user ID.
  1243. *
  1244. * @param sh service context
  1245. * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
  1246. */
  1247. static int
  1248. set_user_id (struct GNUNET_SERVICE_Handle *sh)
  1249. {
  1250. char *user;
  1251. if (NULL == (user = get_user_name (sh)))
  1252. return GNUNET_OK; /* keep */
  1253. #ifndef MINGW
  1254. struct passwd *pws;
  1255. errno = 0;
  1256. pws = getpwnam (user);
  1257. if (NULL == pws)
  1258. {
  1259. LOG (GNUNET_ERROR_TYPE_ERROR,
  1260. _("Cannot obtain information about user `%s': %s\n"),
  1261. user,
  1262. errno == 0 ? _("No such user") : STRERROR (errno));
  1263. GNUNET_free (user);
  1264. return GNUNET_SYSERR;
  1265. }
  1266. if ( (0 != setgid (pws->pw_gid)) ||
  1267. (0 != setegid (pws->pw_gid)) ||
  1268. #if HAVE_INITGROUPS
  1269. (0 != initgroups (user,
  1270. pws->pw_gid)) ||
  1271. #endif
  1272. (0 != setuid (pws->pw_uid)) ||
  1273. (0 != seteuid (pws->pw_uid)))
  1274. {
  1275. if ((0 != setregid (pws->pw_gid,
  1276. pws->pw_gid)) ||
  1277. (0 != setreuid (pws->pw_uid,
  1278. pws->pw_uid)))
  1279. {
  1280. LOG (GNUNET_ERROR_TYPE_ERROR,
  1281. _("Cannot change user/group to `%s': %s\n"),
  1282. user,
  1283. STRERROR (errno));
  1284. GNUNET_free (user);
  1285. return GNUNET_SYSERR;
  1286. }
  1287. }
  1288. #endif
  1289. GNUNET_free (user);
  1290. return GNUNET_OK;
  1291. }
  1292. /**
  1293. * Get the name of the file where we will
  1294. * write the PID of the service.
  1295. *
  1296. * @param sh service context
  1297. * @return name of the file for the process ID
  1298. */
  1299. static char *
  1300. get_pid_file_name (struct GNUNET_SERVICE_Handle *sh)
  1301. {
  1302. char *pif;
  1303. if (GNUNET_OK !=
  1304. GNUNET_CONFIGURATION_get_value_filename (sh->cfg,
  1305. sh->service_name,
  1306. "PIDFILE",
  1307. &pif))
  1308. return NULL;
  1309. return pif;
  1310. }
  1311. /**
  1312. * Delete the PID file that was created by our parent.
  1313. *
  1314. * @param sh service context
  1315. */
  1316. static void
  1317. pid_file_delete (struct GNUNET_SERVICE_Handle *sh)
  1318. {
  1319. char *pif = get_pid_file_name (sh);
  1320. if (NULL == pif)
  1321. return; /* no PID file */
  1322. if (0 != UNLINK (pif))
  1323. LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING,
  1324. "unlink",
  1325. pif);
  1326. GNUNET_free (pif);
  1327. }
  1328. /**
  1329. * Detach from terminal.
  1330. *
  1331. * @param sh service context
  1332. * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
  1333. */
  1334. static int
  1335. detach_terminal (struct GNUNET_SERVICE_Handle *sh)
  1336. {
  1337. #ifndef MINGW
  1338. pid_t pid;
  1339. int nullfd;
  1340. int filedes[2];
  1341. if (0 != PIPE (filedes))
  1342. {
  1343. LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
  1344. "pipe");
  1345. return GNUNET_SYSERR;
  1346. }
  1347. pid = fork ();
  1348. if (pid < 0)
  1349. {
  1350. LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
  1351. "fork");
  1352. return GNUNET_SYSERR;
  1353. }
  1354. if (0 != pid)
  1355. {
  1356. /* Parent */
  1357. char c;
  1358. GNUNET_break (0 == CLOSE (filedes[1]));
  1359. c = 'X';
  1360. if (1 != READ (filedes[0],
  1361. &c,
  1362. sizeof (char)))
  1363. LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING,
  1364. "read");
  1365. fflush (stdout);
  1366. switch (c)
  1367. {
  1368. case '.':
  1369. exit (0);
  1370. case 'I':
  1371. LOG (GNUNET_ERROR_TYPE_INFO,
  1372. _("Service process failed to initialize\n"));
  1373. break;
  1374. case 'S':
  1375. LOG (GNUNET_ERROR_TYPE_INFO,
  1376. _("Service process could not initialize server function\n"));
  1377. break;
  1378. case 'X':
  1379. LOG (GNUNET_ERROR_TYPE_INFO,
  1380. _("Service process failed to report status\n"));
  1381. break;
  1382. }
  1383. exit (1); /* child reported error */
  1384. }
  1385. GNUNET_break (0 == CLOSE (0));
  1386. GNUNET_break (0 == CLOSE (1));
  1387. GNUNET_break (0 == CLOSE (filedes[0]));
  1388. nullfd = OPEN ("/dev/null",
  1389. O_RDWR | O_APPEND);
  1390. if (nullfd < 0)
  1391. return GNUNET_SYSERR;
  1392. /* set stdin/stdout to /dev/null */
  1393. if ( (dup2 (nullfd, 0) < 0) ||
  1394. (dup2 (nullfd, 1) < 0) )
  1395. {
  1396. LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
  1397. "dup2");
  1398. (void) CLOSE (nullfd);
  1399. return GNUNET_SYSERR;
  1400. }
  1401. (void) CLOSE (nullfd);
  1402. /* Detach from controlling terminal */
  1403. pid = setsid ();
  1404. if (-1 == pid)
  1405. LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
  1406. "setsid");
  1407. sh->ready_confirm_fd = filedes[1];
  1408. #else
  1409. /* FIXME: we probably need to do something else
  1410. * elsewhere in order to fork the process itself... */
  1411. FreeConsole ();
  1412. #endif
  1413. return GNUNET_OK;
  1414. }
  1415. /**
  1416. * Tear down the service, closing the listen sockets and
  1417. * freeing the ACLs.
  1418. *
  1419. * @param sh handle to the service to tear down.
  1420. */
  1421. static void
  1422. teardown_service (struct GNUNET_SERVICE_Handle *sh)
  1423. {
  1424. struct ServiceListenContext *slc;
  1425. GNUNET_free_non_null (sh->v4_denied);
  1426. GNUNET_free_non_null (sh->v6_denied);
  1427. GNUNET_free_non_null (sh->v4_allowed);
  1428. GNUNET_free_non_null (sh->v6_allowed);
  1429. while (NULL != (slc = sh->slc_head))
  1430. {
  1431. GNUNET_CONTAINER_DLL_remove (sh->slc_head,
  1432. sh->slc_tail,
  1433. slc);
  1434. if (NULL != slc->listen_task)
  1435. GNUNET_SCHEDULER_cancel (slc->listen_task);
  1436. GNUNET_break (GNUNET_OK ==
  1437. GNUNET_NETWORK_socket_close (slc->listen_socket));
  1438. GNUNET_free (slc);
  1439. }
  1440. }
  1441. /**
  1442. * Low-level function to start a service if the scheduler
  1443. * is already running. Should only be used directly in
  1444. * special cases.
  1445. *
  1446. * The function will launch the service with the name @a service_name
  1447. * using the @a service_options to configure its shutdown
  1448. * behavior. When clients connect or disconnect, the respective
  1449. * @a connect_cb or @a disconnect_cb functions will be called. For
  1450. * messages received from the clients, the respective @a handlers will
  1451. * be invoked; for the closure of the handlers we use the return value
  1452. * from the @a connect_cb invocation of the respective client.
  1453. *
  1454. * Each handler MUST call #GNUNET_SERVICE_client_continue() after each
  1455. * message to receive further messages from this client. If
  1456. * #GNUNET_SERVICE_client_continue() is not called within a short
  1457. * time, a warning will be logged. If delays are expected, services
  1458. * should call #GNUNET_SERVICE_client_disable_continue_warning() to
  1459. * disable the warning.
  1460. *
  1461. * Clients sending invalid messages (based on @a handlers) will be
  1462. * dropped. Additionally, clients can be dropped at any time using
  1463. * #GNUNET_SERVICE_client_drop().
  1464. *
  1465. * The service must be stopped using #GNUNET_SERVICE_stop().
  1466. *
  1467. * @param service_name name of the service to run
  1468. * @param cfg configuration to use
  1469. * @param connect_cb function to call whenever a client connects
  1470. * @param disconnect_cb function to call whenever a client disconnects
  1471. * @param cls closure argument for @a connect_cb and @a disconnect_cb
  1472. * @param handlers NULL-terminated array of message handlers for the service,
  1473. * the closure will be set to the value returned by
  1474. * the @a connect_cb for the respective connection
  1475. * @return NULL on error
  1476. */
  1477. struct GNUNET_SERVICE_Handle *
  1478. GNUNET_SERVICE_start (const char *service_name,
  1479. const struct GNUNET_CONFIGURATION_Handle *cfg,
  1480. GNUNET_SERVICE_ConnectHandler connect_cb,
  1481. GNUNET_SERVICE_DisconnectHandler disconnect_cb,
  1482. void *cls,
  1483. const struct GNUNET_MQ_MessageHandler *handlers)
  1484. {
  1485. struct GNUNET_SERVICE_Handle *sh;
  1486. sh = GNUNET_new (struct GNUNET_SERVICE_Handle);
  1487. sh->service_name = service_name;
  1488. sh->cfg = cfg;
  1489. sh->connect_cb = connect_cb;
  1490. sh->disconnect_cb = disconnect_cb;
  1491. sh->cb_cls = cls;
  1492. sh->handlers = GNUNET_MQ_copy_handlers (handlers);
  1493. if (GNUNET_OK != setup_service (sh))
  1494. {
  1495. GNUNET_free_non_null (sh->handlers);
  1496. GNUNET_free (sh);
  1497. return NULL;
  1498. }
  1499. GNUNET_SERVICE_resume (sh);
  1500. return sh;
  1501. }
  1502. /**
  1503. * Stops a service that was started with #GNUNET_SERVICE_start().
  1504. *
  1505. * @param srv service to stop
  1506. */
  1507. void
  1508. GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Handle *srv)
  1509. {
  1510. struct GNUNET_SERVICE_Client *client;
  1511. GNUNET_SERVICE_suspend (srv);
  1512. while (NULL != (client = srv->clients_head))
  1513. GNUNET_SERVICE_client_drop (client);
  1514. teardown_service (srv);
  1515. GNUNET_free_non_null (srv->handlers);
  1516. GNUNET_free (srv);
  1517. }
  1518. /**
  1519. * Creates the "main" function for a GNUnet service. You
  1520. * should almost always use the #GNUNET_SERVICE_MAIN macro
  1521. * instead of calling this function directly (except
  1522. * for ARM, which should call this function directly).
  1523. *
  1524. * The function will launch the service with the name @a service_name
  1525. * using the @a service_options to configure its shutdown
  1526. * behavior. Once the service is ready, the @a init_cb will be called
  1527. * for service-specific initialization. @a init_cb will be given the
  1528. * service handler which can be used to control the service's
  1529. * availability. When clients connect or disconnect, the respective
  1530. * @a connect_cb or @a disconnect_cb functions will be called. For
  1531. * messages received from the clients, the respective @a handlers will
  1532. * be invoked; for the closure of the handlers we use the return value
  1533. * from the @a connect_cb invocation of the respective client.
  1534. *
  1535. * Each handler MUST call #GNUNET_SERVICE_client_continue() after each
  1536. * message to receive further messages from this client. If
  1537. * #GNUNET_SERVICE_client_continue() is not called within a short
  1538. * time, a warning will be logged. If delays are expected, services
  1539. * should call #GNUNET_SERVICE_client_disable_continue_warning() to
  1540. * disable the warning.
  1541. *
  1542. * Clients sending invalid messages (based on @a handlers) will be
  1543. * dropped. Additionally, clients can be dropped at any time using
  1544. * #GNUNET_SERVICE_client_drop().
  1545. *
  1546. * @param argc number of command-line arguments in @a argv
  1547. * @param argv array of command-line arguments
  1548. * @param service_name name of the service to run
  1549. * @param options options controlling shutdown of the service
  1550. * @param service_init_cb function to call once the service is ready
  1551. * @param connect_cb function to call whenever a client connects
  1552. * @param disconnect_cb function to call whenever a client disconnects
  1553. * @param cls closure argument for @a service_init_cb, @a connect_cb and @a disconnect_cb
  1554. * @param handlers NULL-terminated array of message handlers for the service,
  1555. * the closure will be set to the value returned by
  1556. * the @a connect_cb for the respective connection
  1557. * @return 0 on success, non-zero on error
  1558. */
  1559. int
  1560. GNUNET_SERVICE_run_ (int argc,
  1561. char *const *argv,
  1562. const char *service_name,
  1563. enum GNUNET_SERVICE_Options options,
  1564. GNUNET_SERVICE_InitCallback service_init_cb,
  1565. GNUNET_SERVICE_ConnectHandler connect_cb,
  1566. GNUNET_SERVICE_DisconnectHandler disconnect_cb,
  1567. void *cls,
  1568. const struct GNUNET_MQ_MessageHandler *handlers)
  1569. {
  1570. struct GNUNET_SERVICE_Handle sh;
  1571. char *cfg_filename;
  1572. char *opt_cfg_filename;
  1573. char *loglev;
  1574. const char *xdg;
  1575. char *logfile;
  1576. int do_daemonize;
  1577. unsigned long long skew_offset;
  1578. unsigned long long skew_variance;
  1579. long long clock_offset;
  1580. struct GNUNET_CONFIGURATION_Handle *cfg;
  1581. int ret;
  1582. int err;
  1583. struct GNUNET_GETOPT_CommandLineOption service_options[] = {
  1584. GNUNET_GETOPT_option_cfgfile (&opt_cfg_filename),
  1585. GNUNET_GETOPT_option_flag ('d',
  1586. "daemonize",
  1587. gettext_noop ("do daemonize (detach from terminal)"),
  1588. &do_daemonize),
  1589. GNUNET_GETOPT_option_help (NULL),
  1590. GNUNET_GETOPT_option_loglevel (&loglev),
  1591. GNUNET_GETOPT_option_logfile (&logfile),
  1592. GNUNET_GETOPT_option_version (PACKAGE_VERSION " " VCS_VERSION),
  1593. GNUNET_GETOPT_OPTION_END
  1594. };
  1595. err = 1;
  1596. memset (&sh,
  1597. 0,
  1598. sizeof (sh));
  1599. xdg = getenv ("XDG_CONFIG_HOME");
  1600. if (NULL != xdg)
  1601. GNUNET_asprintf (&cfg_filename,
  1602. "%s%s%s",
  1603. xdg,
  1604. DIR_SEPARATOR_STR,
  1605. GNUNET_OS_project_data_get ()->config_file);
  1606. else
  1607. cfg_filename = GNUNET_strdup (GNUNET_OS_project_data_get ()->user_config_file);
  1608. sh.ready_confirm_fd = -1;
  1609. sh.options = options;
  1610. sh.cfg = cfg = GNUNET_CONFIGURATION_create ();
  1611. sh.service_init_cb = service_init_cb;
  1612. sh.connect_cb = connect_cb;
  1613. sh.disconnect_cb = disconnect_cb;
  1614. sh.cb_cls = cls;
  1615. sh.handlers = GNUNET_MQ_copy_handlers (handlers);
  1616. sh.service_name = service_name;
  1617. /* setup subsystems */
  1618. loglev = NULL;
  1619. logfile = NULL;
  1620. opt_cfg_filename = NULL;
  1621. do_daemonize = 0;
  1622. ret = GNUNET_GETOPT_run (service_name,
  1623. service_options,
  1624. argc,
  1625. argv);
  1626. if (GNUNET_SYSERR == ret)
  1627. goto shutdown;
  1628. if (GNUNET_NO == ret)
  1629. {
  1630. err = 0;
  1631. goto shutdown;
  1632. }
  1633. if (GNUNET_OK != GNUNET_log_setup (service_name,
  1634. loglev,
  1635. logfile))
  1636. {
  1637. GNUNET_break (0);
  1638. goto shutdown;
  1639. }
  1640. if (NULL == opt_cfg_filename)
  1641. opt_cfg_filename = GNUNET_strdup (cfg_filename);
  1642. if (GNUNET_YES == GNUNET_DISK_file_test (opt_cfg_filename))
  1643. {
  1644. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg,
  1645. opt_cfg_filename))
  1646. {
  1647. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  1648. _("Malformed configuration file `%s', exit ...\n"),
  1649. opt_cfg_filename);
  1650. goto shutdown;
  1651. }
  1652. }
  1653. else
  1654. {
  1655. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg,
  1656. NULL))
  1657. {
  1658. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  1659. _("Malformed configuration, exit ...\n"));
  1660. goto shutdown;
  1661. }
  1662. if (0 != strcmp (opt_cfg_filename,
  1663. cfg_filename))
  1664. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  1665. _("Could not access configuration file `%s'\n"),
  1666. opt_cfg_filename);
  1667. }
  1668. if (GNUNET_OK != setup_service (&sh))
  1669. goto shutdown;
  1670. if ( (1 == do_daemonize) &&
  1671. (GNUNET_OK != detach_terminal (&sh)) )
  1672. {
  1673. GNUNET_break (0);
  1674. goto shutdown;
  1675. }
  1676. if (GNUNET_OK != set_user_id (&sh))
  1677. goto shutdown;
  1678. LOG (GNUNET_ERROR_TYPE_DEBUG,
  1679. "Service `%s' runs with configuration from `%s'\n",
  1680. service_name,
  1681. opt_cfg_filename);
  1682. if ((GNUNET_OK ==
  1683. GNUNET_CONFIGURATION_get_value_number (sh.cfg,
  1684. "TESTING",
  1685. "SKEW_OFFSET",
  1686. &skew_offset)) &&
  1687. (GNUNET_OK ==
  1688. GNUNET_CONFIGURATION_get_value_number (sh.cfg,
  1689. "TESTING",
  1690. "SKEW_VARIANCE",
  1691. &skew_variance)))
  1692. {
  1693. clock_offset = skew_offset - skew_variance;
  1694. GNUNET_TIME_set_offset (clock_offset);
  1695. LOG (GNUNET_ERROR_TYPE_DEBUG,
  1696. "Skewing clock by %dll ms\n",
  1697. clock_offset);
  1698. }
  1699. GNUNET_RESOLVER_connect (sh.cfg);
  1700. /* actually run service */
  1701. err = 0;
  1702. GNUNET_SCHEDULER_run (&service_main,
  1703. &sh);
  1704. /* shutdown */
  1705. if (1 == do_daemonize)
  1706. pid_file_delete (&sh);
  1707. shutdown:
  1708. if (-1 != sh.ready_confirm_fd)
  1709. {
  1710. if (1 != WRITE (sh.ready_confirm_fd,
  1711. err ? "I" : "S",
  1712. 1))
  1713. LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING,
  1714. "write");
  1715. GNUNET_break (0 == CLOSE (sh.ready_confirm_fd));
  1716. }
  1717. #if HAVE_MALLINFO
  1718. {
  1719. char *counter;
  1720. if ( (GNUNET_YES ==
  1721. GNUNET_CONFIGURATION_have_value (sh.cfg,
  1722. service_name,
  1723. "GAUGER_HEAP")) &&
  1724. (GNUNET_OK ==
  1725. GNUNET_CONFIGURATION_get_value_string (sh.cfg,
  1726. service_name,
  1727. "GAUGER_HEAP",
  1728. &counter)) )
  1729. {
  1730. struct mallinfo mi;
  1731. mi = mallinfo ();
  1732. GAUGER (service_name,
  1733. counter,
  1734. mi.usmblks,
  1735. "blocks");
  1736. GNUNET_free (counter);
  1737. }
  1738. }
  1739. #endif
  1740. teardown_service (&sh);
  1741. GNUNET_free_non_null (sh.handlers);
  1742. GNUNET_SPEEDUP_stop_ ();
  1743. GNUNET_CONFIGURATION_destroy (cfg);
  1744. GNUNET_free_non_null (logfile);
  1745. GNUNET_free_non_null (loglev);
  1746. GNUNET_free (cfg_filename);
  1747. GNUNET_free_non_null (opt_cfg_filename);
  1748. return err ? GNUNET_SYSERR : sh.ret;
  1749. }
  1750. /**
  1751. * Suspend accepting connections from the listen socket temporarily.
  1752. * Resume activity using #GNUNET_SERVICE_resume.
  1753. *
  1754. * @param sh service to stop accepting connections.
  1755. */
  1756. void
  1757. GNUNET_SERVICE_suspend (struct GNUNET_SERVICE_Handle *sh)
  1758. {
  1759. struct ServiceListenContext *slc;
  1760. for (slc = sh->slc_head; NULL != slc; slc = slc->next)
  1761. {
  1762. if (NULL != slc->listen_task)
  1763. {
  1764. GNUNET_SCHEDULER_cancel (slc->listen_task);
  1765. slc->listen_task = NULL;
  1766. }
  1767. }
  1768. }
  1769. /**
  1770. * Task run when we are ready to transmit data to the
  1771. * client.
  1772. *
  1773. * @param cls the `struct GNUNET_SERVICE_Client *` to send to
  1774. */
  1775. static void
  1776. do_send (void *cls)
  1777. {
  1778. struct GNUNET_SERVICE_Client *client = cls;
  1779. ssize_t ret;
  1780. size_t left;
  1781. const char *buf;
  1782. client->send_task = NULL;
  1783. buf = (const char *) client->msg;
  1784. left = ntohs (client->msg->size) - client->msg_pos;
  1785. ret = GNUNET_NETWORK_socket_send (client->sock,
  1786. &buf[client->msg_pos],
  1787. left);
  1788. GNUNET_assert (ret <= (ssize_t) left);
  1789. if (0 == ret)
  1790. {
  1791. GNUNET_MQ_inject_error (client->mq,
  1792. GNUNET_MQ_ERROR_WRITE);
  1793. return;
  1794. }
  1795. if (-1 == ret)
  1796. {
  1797. if ( (EAGAIN == errno) ||
  1798. (EINTR == errno) )
  1799. {
  1800. /* ignore */
  1801. ret = 0;
  1802. }
  1803. else
  1804. {
  1805. if (EPIPE != errno)
  1806. GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
  1807. "send");
  1808. GNUNET_MQ_inject_error (client->mq,
  1809. GNUNET_MQ_ERROR_WRITE);
  1810. return;
  1811. }
  1812. }
  1813. if (0 == client->msg_pos)
  1814. {
  1815. GNUNET_MQ_impl_send_in_flight (client->mq);
  1816. }
  1817. client->msg_pos += ret;
  1818. if (left > ret)
  1819. {
  1820. GNUNET_assert (NULL == client->drop_task);
  1821. client->send_task
  1822. = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
  1823. client->sock,
  1824. &do_send,
  1825. client);
  1826. return;
  1827. }
  1828. GNUNET_MQ_impl_send_continue (client->mq);
  1829. }
  1830. /**
  1831. * Signature of functions implementing the sending functionality of a
  1832. * message queue.
  1833. *
  1834. * @param mq the message queue
  1835. * @param msg the message to send
  1836. * @param impl_state our `struct GNUNET_SERVICE_Client *`
  1837. */
  1838. static void
  1839. service_mq_send (struct GNUNET_MQ_Handle *mq,
  1840. const struct GNUNET_MessageHeader *msg,
  1841. void *impl_state)
  1842. {
  1843. struct GNUNET_SERVICE_Client *client = impl_state;
  1844. if (NULL != client->drop_task)
  1845. return; /* we're going down right now, do not try to send */
  1846. GNUNET_assert (NULL == client->send_task);
  1847. LOG (GNUNET_ERROR_TYPE_DEBUG,
  1848. "Sending message of type %u and size %u to client\n",
  1849. ntohs (msg->type),
  1850. ntohs (msg->size));
  1851. client->msg = msg;
  1852. client->msg_pos = 0;
  1853. client->send_task
  1854. = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
  1855. client->sock,
  1856. &do_send,
  1857. client);
  1858. }
  1859. /**
  1860. * Implementation function that cancels the currently sent message.
  1861. *
  1862. * @param mq message queue
  1863. * @param impl_state state specific to the implementation
  1864. */
  1865. static void
  1866. service_mq_cancel (struct GNUNET_MQ_Handle *mq,
  1867. void *impl_state)
  1868. {
  1869. struct GNUNET_SERVICE_Client *client = impl_state;
  1870. GNUNET_assert (0 == client->msg_pos);
  1871. client->msg = NULL;
  1872. GNUNET_SCHEDULER_cancel (client->send_task);
  1873. client->send_task = NULL;
  1874. }
  1875. /**
  1876. * Generic error handler, called with the appropriate
  1877. * error code and the same closure specified at the creation of
  1878. * the message queue.
  1879. * Not every message queue implementation supports an error handler.
  1880. *
  1881. * @param cls closure with our `struct GNUNET_SERVICE_Client`
  1882. * @param error error code
  1883. */
  1884. static void
  1885. service_mq_error_handler (void *cls,
  1886. enum GNUNET_MQ_Error error)
  1887. {
  1888. struct GNUNET_SERVICE_Client *client = cls;
  1889. struct GNUNET_SERVICE_Handle *sh = client->sh;
  1890. if ( (GNUNET_MQ_ERROR_NO_MATCH == error) &&
  1891. (GNUNET_NO == sh->require_found) )
  1892. {
  1893. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  1894. "No handler for message of type %u found\n",
  1895. (unsigned int) client->warn_type);
  1896. GNUNET_SERVICE_client_continue (client);
  1897. return; /* ignore error */
  1898. }
  1899. GNUNET_SERVICE_client_drop (client);
  1900. }
  1901. /**
  1902. * Task run to warn about missing calls to #GNUNET_SERVICE_client_continue().
  1903. *
  1904. * @param cls our `struct GNUNET_SERVICE_Client *` to process more requests from
  1905. */
  1906. static void
  1907. warn_no_client_continue (void *cls)
  1908. {
  1909. struct GNUNET_SERVICE_Client *client = cls;
  1910. GNUNET_break (0 != client->warn_type); /* type should never be 0 here, as we don't use 0 */
  1911. client->warn_task
  1912. = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
  1913. &warn_no_client_continue,
  1914. client);
  1915. LOG (GNUNET_ERROR_TYPE_WARNING,
  1916. _("Processing code for message of type %u did not call `GNUNET_SERVICE_client_continue' after %s\n"),
  1917. (unsigned int) client->warn_type,
  1918. GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (client->warn_start),
  1919. GNUNET_YES));
  1920. }
  1921. /**
  1922. * Functions with this signature are called whenever a
  1923. * complete message is received by the tokenizer for a client.
  1924. *
  1925. * Do not call #GNUNET_MST_destroy() from within
  1926. * the scope of this callback.
  1927. *
  1928. * @param cls closure with the `struct GNUNET_SERVICE_Client *`
  1929. * @param message the actual message
  1930. * @return #GNUNET_OK on success, #GNUNET_SYSERR if the client was dropped
  1931. */
  1932. static int
  1933. service_client_mst_cb (void *cls,
  1934. const struct GNUNET_MessageHeader *message)
  1935. {
  1936. struct GNUNET_SERVICE_Client *client = cls;
  1937. LOG (GNUNET_ERROR_TYPE_DEBUG,
  1938. "Received message of type %u and size %u from client\n",
  1939. ntohs (message->type),
  1940. ntohs (message->size));
  1941. GNUNET_assert (GNUNET_NO == client->needs_continue);
  1942. client->needs_continue = GNUNET_YES;
  1943. client->warn_type = ntohs (message->type);
  1944. client->warn_start = GNUNET_TIME_absolute_get ();
  1945. GNUNET_assert (NULL == client->warn_task);
  1946. client->warn_task
  1947. = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
  1948. &warn_no_client_continue,
  1949. client);
  1950. GNUNET_MQ_inject_message (client->mq,
  1951. message);
  1952. if (NULL != client->drop_task)
  1953. return GNUNET_SYSERR;
  1954. return GNUNET_OK;
  1955. }
  1956. /**
  1957. * A client sent us data. Receive and process it. If we are done,
  1958. * reschedule this task.
  1959. *
  1960. * @param cls the `struct GNUNET_SERVICE_Client` that sent us data.
  1961. */
  1962. static void
  1963. service_client_recv (void *cls)
  1964. {
  1965. struct GNUNET_SERVICE_Client *client = cls;
  1966. int ret;
  1967. client->recv_task = NULL;
  1968. ret = GNUNET_MST_read (client->mst,
  1969. client->sock,
  1970. GNUNET_NO,
  1971. GNUNET_YES);
  1972. if (GNUNET_SYSERR == ret)
  1973. {
  1974. /* client closed connection (or IO error) */
  1975. if (NULL == client->drop_task)
  1976. {
  1977. GNUNET_assert (GNUNET_NO == client->needs_continue);
  1978. GNUNET_SERVICE_client_drop (client);
  1979. }
  1980. return;
  1981. }
  1982. if (GNUNET_NO == ret)
  1983. return; /* more messages in buffer, wait for application
  1984. to be done processing */
  1985. GNUNET_assert (GNUNET_OK == ret);
  1986. if (GNUNET_YES == client->needs_continue)
  1987. return;
  1988. if (NULL != client->recv_task)
  1989. return;
  1990. /* MST needs more data, re-schedule read job */
  1991. client->recv_task
  1992. = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
  1993. client->sock,
  1994. &service_client_recv,
  1995. client);
  1996. }
  1997. /**
  1998. * We have successfully accepted a connection from a client. Now
  1999. * setup the client (with the scheduler) and tell the application.
  2000. *
  2001. * @param sh service that accepted the client
  2002. * @param sock socket associated with the client
  2003. */
  2004. static void
  2005. start_client (struct GNUNET_SERVICE_Handle *sh,
  2006. struct GNUNET_NETWORK_Handle *csock)
  2007. {
  2008. struct GNUNET_SERVICE_Client *client;
  2009. client = GNUNET_new (struct GNUNET_SERVICE_Client);
  2010. GNUNET_CONTAINER_DLL_insert (sh->clients_head,
  2011. sh->clients_tail,
  2012. client);
  2013. client->sh = sh;
  2014. client->sock = csock;
  2015. client->mq = GNUNET_MQ_queue_for_callbacks (&service_mq_send,
  2016. NULL,
  2017. &service_mq_cancel,
  2018. client,
  2019. sh->handlers,
  2020. &service_mq_error_handler,
  2021. client);
  2022. client->mst = GNUNET_MST_create (&service_client_mst_cb,
  2023. client);
  2024. if (NULL != sh->connect_cb)
  2025. client->user_context = sh->connect_cb (sh->cb_cls,
  2026. client,
  2027. client->mq);
  2028. GNUNET_MQ_set_handlers_closure (client->mq,
  2029. client->user_context);
  2030. client->recv_task
  2031. = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
  2032. client->sock,
  2033. &service_client_recv,
  2034. client);
  2035. }
  2036. /**
  2037. * Check if the given IP address is in the list of IP addresses.
  2038. *
  2039. * @param list a list of networks
  2040. * @param add the IP to check (in network byte order)
  2041. * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is
  2042. */
  2043. static int
  2044. check_ipv4_listed (const struct GNUNET_STRINGS_IPv4NetworkPolicy *list,
  2045. const struct in_addr *add)
  2046. {
  2047. unsigned int i;
  2048. if (NULL == list)
  2049. return GNUNET_NO;
  2050. i = 0;
  2051. while ( (0 != list[i].network.s_addr) ||
  2052. (0 != list[i].netmask.s_addr) )
  2053. {
  2054. if ((add->s_addr & list[i].netmask.s_addr) ==
  2055. (list[i].network.s_addr & list[i].netmask.s_addr))
  2056. return GNUNET_YES;
  2057. i++;
  2058. }
  2059. return GNUNET_NO;
  2060. }
  2061. /**
  2062. * Check if the given IP address is in the list of IP addresses.
  2063. *
  2064. * @param list a list of networks
  2065. * @param ip the IP to check (in network byte order)
  2066. * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is
  2067. */
  2068. static int
  2069. check_ipv6_listed (const struct GNUNET_STRINGS_IPv6NetworkPolicy *list,
  2070. const struct in6_addr *ip)
  2071. {
  2072. unsigned int i;
  2073. unsigned int j;
  2074. struct in6_addr zero;
  2075. if (NULL == list)
  2076. return GNUNET_NO;
  2077. memset (&zero,
  2078. 0,
  2079. sizeof (struct in6_addr));
  2080. i = 0;
  2081. NEXT:
  2082. while (0 != memcmp (&zero,
  2083. &list[i].network,
  2084. sizeof (struct in6_addr)))
  2085. {
  2086. for (j = 0; j < sizeof (struct in6_addr) / sizeof (int); j++)
  2087. if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) !=
  2088. (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j]))
  2089. {
  2090. i++;
  2091. goto NEXT;
  2092. }
  2093. return GNUNET_YES;
  2094. }
  2095. return GNUNET_NO;
  2096. }
  2097. /**
  2098. * We have a client. Accept the incoming socket(s) (and reschedule
  2099. * the listen task).
  2100. *
  2101. * @param cls the `struct ServiceListenContext` of the ready listen socket
  2102. */
  2103. static void
  2104. accept_client (void *cls)
  2105. {
  2106. struct ServiceListenContext *slc = cls;
  2107. struct GNUNET_SERVICE_Handle *sh = slc->sh;
  2108. slc->listen_task = NULL;
  2109. while (1)
  2110. {
  2111. struct GNUNET_NETWORK_Handle *sock;
  2112. const struct sockaddr_in *v4;
  2113. const struct sockaddr_in6 *v6;
  2114. struct sockaddr_storage sa;
  2115. socklen_t addrlen;
  2116. int ok;
  2117. addrlen = sizeof (sa);
  2118. sock = GNUNET_NETWORK_socket_accept (slc->listen_socket,
  2119. (struct sockaddr *) &sa,
  2120. &addrlen);
  2121. if (NULL == sock)
  2122. break;
  2123. switch (sa.ss_family)
  2124. {
  2125. case AF_INET:
  2126. GNUNET_assert (addrlen == sizeof (struct sockaddr_in));
  2127. v4 = (const struct sockaddr_in *) &sa;
  2128. ok = ( ( (NULL == sh->v4_allowed) ||
  2129. (check_ipv4_listed (sh->v4_allowed,
  2130. &v4->sin_addr))) &&
  2131. ( (NULL == sh->v4_denied) ||
  2132. (! check_ipv4_listed (sh->v4_denied,
  2133. &v4->sin_addr)) ) );
  2134. break;
  2135. case AF_INET6:
  2136. GNUNET_assert (addrlen == sizeof (struct sockaddr_in6));
  2137. v6 = (const struct sockaddr_in6 *) &sa;
  2138. ok = ( ( (NULL == sh->v6_allowed) ||
  2139. (check_ipv6_listed (sh->v6_allowed,
  2140. &v6->sin6_addr))) &&
  2141. ( (NULL == sh->v6_denied) ||
  2142. (! check_ipv6_listed (sh->v6_denied,
  2143. &v6->sin6_addr)) ) );
  2144. break;
  2145. #ifndef WINDOWS
  2146. case AF_UNIX:
  2147. ok = GNUNET_OK; /* controlled using file-system ACL now */
  2148. break;
  2149. #endif
  2150. default:
  2151. LOG (GNUNET_ERROR_TYPE_WARNING,
  2152. _("Unknown address family %d\n"),
  2153. sa.ss_family);
  2154. return;
  2155. }
  2156. if (! ok)
  2157. {
  2158. LOG (GNUNET_ERROR_TYPE_DEBUG,
  2159. "Service rejected incoming connection from %s due to policy.\n",
  2160. GNUNET_a2s ((const struct sockaddr *) &sa,
  2161. addrlen));
  2162. GNUNET_break (GNUNET_OK ==
  2163. GNUNET_NETWORK_socket_close (sock));
  2164. continue;
  2165. }
  2166. LOG (GNUNET_ERROR_TYPE_DEBUG,
  2167. "Service accepted incoming connection from %s.\n",
  2168. GNUNET_a2s ((const struct sockaddr *) &sa,
  2169. addrlen));
  2170. start_client (slc->sh,
  2171. sock);
  2172. }
  2173. slc->listen_task
  2174. = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
  2175. slc->listen_socket,
  2176. &accept_client,
  2177. slc);
  2178. }
  2179. /**
  2180. * Resume accepting connections from the listen socket.
  2181. *
  2182. * @param sh service to resume accepting connections.
  2183. */
  2184. void
  2185. GNUNET_SERVICE_resume (struct GNUNET_SERVICE_Handle *sh)
  2186. {
  2187. struct ServiceListenContext *slc;
  2188. for (slc = sh->slc_head; NULL != slc; slc = slc->next)
  2189. {
  2190. GNUNET_assert (NULL == slc->listen_task);
  2191. slc->listen_task
  2192. = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
  2193. slc->listen_socket,
  2194. &accept_client,
  2195. slc);
  2196. }
  2197. }
  2198. /**
  2199. * Task run to resume receiving data from the client after
  2200. * the client called #GNUNET_SERVICE_client_continue().
  2201. *
  2202. * @param cls our `struct GNUNET_SERVICE_Client`
  2203. */
  2204. static void
  2205. resume_client_receive (void *cls)
  2206. {
  2207. struct GNUNET_SERVICE_Client *c = cls;
  2208. int ret;
  2209. c->recv_task = NULL;
  2210. /* first, check if there is still something in the buffer */
  2211. ret = GNUNET_MST_next (c->mst,
  2212. GNUNET_YES);
  2213. if (GNUNET_SYSERR == ret)
  2214. {
  2215. if (NULL != c->drop_task)
  2216. GNUNET_SERVICE_client_drop (c);
  2217. return;
  2218. }
  2219. if (GNUNET_NO == ret)
  2220. return; /* done processing, wait for more later */
  2221. GNUNET_assert (GNUNET_OK == ret);
  2222. if (GNUNET_YES == c->needs_continue)
  2223. return; /* #GNUNET_MST_next() did give a message to the client */
  2224. /* need to receive more data from the network first */
  2225. if (NULL != c->recv_task)
  2226. return;
  2227. c->recv_task
  2228. = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
  2229. c->sock,
  2230. &service_client_recv,
  2231. c);
  2232. }
  2233. /**
  2234. * Continue receiving further messages from the given client.
  2235. * Must be called after each message received.
  2236. *
  2237. * @param c the client to continue receiving from
  2238. */
  2239. void
  2240. GNUNET_SERVICE_client_continue (struct GNUNET_SERVICE_Client *c)
  2241. {
  2242. GNUNET_assert (GNUNET_YES == c->needs_continue);
  2243. GNUNET_assert (NULL == c->recv_task);
  2244. c->needs_continue = GNUNET_NO;
  2245. if (NULL != c->warn_task)
  2246. {
  2247. GNUNET_SCHEDULER_cancel (c->warn_task);
  2248. c->warn_task = NULL;
  2249. }
  2250. c->recv_task
  2251. = GNUNET_SCHEDULER_add_now (&resume_client_receive,
  2252. c);
  2253. }
  2254. /**
  2255. * Disable the warning the server issues if a message is not
  2256. * acknowledged in a timely fashion. Use this call if a client is
  2257. * intentionally delayed for a while. Only applies to the current
  2258. * message.
  2259. *
  2260. * @param c client for which to disable the warning
  2261. */
  2262. void
  2263. GNUNET_SERVICE_client_disable_continue_warning (struct GNUNET_SERVICE_Client *c)
  2264. {
  2265. GNUNET_break (NULL != c->warn_task);
  2266. if (NULL != c->warn_task)
  2267. {
  2268. GNUNET_SCHEDULER_cancel (c->warn_task);
  2269. c->warn_task = NULL;
  2270. }
  2271. }
  2272. /**
  2273. * Asynchronously finish dropping the client.
  2274. *
  2275. * @param cls the `struct GNUNET_SERVICE_Client`.
  2276. */
  2277. static void
  2278. finish_client_drop (void *cls)
  2279. {
  2280. struct GNUNET_SERVICE_Client *c = cls;
  2281. struct GNUNET_SERVICE_Handle *sh = c->sh;
  2282. c->drop_task = NULL;
  2283. GNUNET_assert (NULL == c->send_task);
  2284. GNUNET_assert (NULL == c->recv_task);
  2285. GNUNET_assert (NULL == c->warn_task);
  2286. GNUNET_MST_destroy (c->mst);
  2287. GNUNET_MQ_destroy (c->mq);
  2288. if (GNUNET_NO == c->persist)
  2289. {
  2290. GNUNET_break (GNUNET_OK ==
  2291. GNUNET_NETWORK_socket_close (c->sock));
  2292. }
  2293. else
  2294. {
  2295. GNUNET_NETWORK_socket_free_memory_only_ (c->sock);
  2296. }
  2297. GNUNET_free (c);
  2298. if ( (GNUNET_YES == sh->got_shutdown) &&
  2299. (GNUNET_NO == have_non_monitor_clients (sh)) )
  2300. GNUNET_SERVICE_shutdown (sh);
  2301. }
  2302. /**
  2303. * Ask the server to disconnect from the given client. This is the
  2304. * same as returning #GNUNET_SYSERR within the check procedure when
  2305. * handling a message, wexcept that it allows dropping of a client even
  2306. * when not handling a message from that client. The `disconnect_cb`
  2307. * will be called on @a c even if the application closes the connection
  2308. * using this function.
  2309. *
  2310. * @param c client to disconnect now
  2311. */
  2312. void
  2313. GNUNET_SERVICE_client_drop (struct GNUNET_SERVICE_Client *c)
  2314. {
  2315. struct GNUNET_SERVICE_Handle *sh = c->sh;
  2316. if (NULL != c->drop_task)
  2317. {
  2318. /* asked to drop twice! */
  2319. GNUNET_assert (0);
  2320. return;
  2321. }
  2322. GNUNET_CONTAINER_DLL_remove (sh->clients_head,
  2323. sh->clients_tail,
  2324. c);
  2325. if (NULL != sh->disconnect_cb)
  2326. sh->disconnect_cb (sh->cb_cls,
  2327. c,
  2328. c->user_context);
  2329. if (NULL != c->warn_task)
  2330. {
  2331. GNUNET_SCHEDULER_cancel (c->warn_task);
  2332. c->warn_task = NULL;
  2333. }
  2334. if (NULL != c->recv_task)
  2335. {
  2336. GNUNET_SCHEDULER_cancel (c->recv_task);
  2337. c->recv_task = NULL;
  2338. }
  2339. if (NULL != c->send_task)
  2340. {
  2341. GNUNET_SCHEDULER_cancel (c->send_task);
  2342. c->send_task = NULL;
  2343. }
  2344. c->drop_task = GNUNET_SCHEDULER_add_now (&finish_client_drop,
  2345. c);
  2346. }
  2347. /**
  2348. * Explicitly stops the service.
  2349. *
  2350. * @param sh server to shutdown
  2351. */
  2352. void
  2353. GNUNET_SERVICE_shutdown (struct GNUNET_SERVICE_Handle *sh)
  2354. {
  2355. struct GNUNET_SERVICE_Client *client;
  2356. GNUNET_SERVICE_suspend (sh);
  2357. sh->got_shutdown = GNUNET_NO;
  2358. while (NULL != (client = sh->clients_head))
  2359. GNUNET_SERVICE_client_drop (client);
  2360. }
  2361. /**
  2362. * Set the 'monitor' flag on this client. Clients which have been
  2363. * marked as 'monitors' won't prevent the server from shutting down
  2364. * once #GNUNET_SERVICE_stop_listening() has been invoked. The idea is
  2365. * that for "normal" clients we likely want to allow them to process
  2366. * their requests; however, monitor-clients are likely to 'never'
  2367. * disconnect during shutdown and thus will not be considered when
  2368. * determining if the server should continue to exist after
  2369. * shutdown has been triggered.
  2370. *
  2371. * @param c client to mark as a monitor
  2372. */
  2373. void
  2374. GNUNET_SERVICE_client_mark_monitor (struct GNUNET_SERVICE_Client *c)
  2375. {
  2376. c->is_monitor = GNUNET_YES;
  2377. if ( (GNUNET_YES == c->sh->got_shutdown) &&
  2378. (GNUNET_NO == have_non_monitor_clients (c->sh)) )
  2379. GNUNET_SERVICE_shutdown (c->sh);
  2380. }
  2381. /**
  2382. * Set the persist option on this client. Indicates that the
  2383. * underlying socket or fd should never really be closed. Used for
  2384. * indicating process death.
  2385. *
  2386. * @param c client to persist the socket (never to be closed)
  2387. */
  2388. void
  2389. GNUNET_SERVICE_client_persist (struct GNUNET_SERVICE_Client *c)
  2390. {
  2391. c->persist = GNUNET_YES;
  2392. }
  2393. /**
  2394. * Obtain the message queue of @a c. Convenience function.
  2395. *
  2396. * @param c the client to continue receiving from
  2397. * @return the message queue of @a c
  2398. */
  2399. struct GNUNET_MQ_Handle *
  2400. GNUNET_SERVICE_client_get_mq (struct GNUNET_SERVICE_Client *c)
  2401. {
  2402. return c->mq;
  2403. }
  2404. /* end of service_new.c */