conn.c 66 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529
  1. /*
  2. * ngIRCd -- The Next Generation IRC Daemon
  3. * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. * Please read the file COPYING, README and AUTHORS for more information.
  10. */
  11. #undef DEBUG_BUFFER
  12. #define CONN_MODULE
  13. #include "portab.h"
  14. #include "conf-ssl.h"
  15. #include "io.h"
  16. /**
  17. * @file
  18. * Connection management
  19. */
  20. #include "imp.h"
  21. #include <assert.h>
  22. #ifdef PROTOTYPES
  23. # include <stdarg.h>
  24. #else
  25. # include <varargs.h>
  26. #endif
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <unistd.h>
  30. #include <errno.h>
  31. #include <string.h>
  32. #include <sys/socket.h>
  33. #include <sys/time.h>
  34. #include <sys/types.h>
  35. #include <time.h>
  36. #include <netinet/in.h>
  37. #ifdef HAVE_NETINET_IP_H
  38. # ifdef HAVE_NETINET_IN_SYSTM_H
  39. # include <netinet/in_systm.h>
  40. # endif
  41. # include <netinet/ip.h>
  42. #endif
  43. #ifdef TCPWRAP
  44. # include <tcpd.h> /* for TCP Wrappers */
  45. #endif
  46. #include "array.h"
  47. #include "defines.h"
  48. #include "exp.h"
  49. #include "conn.h"
  50. #include "imp.h"
  51. #include "ngircd.h"
  52. #include "array.h"
  53. #include "client.h"
  54. #include "class.h"
  55. #include "conf.h"
  56. #include "conn-encoding.h"
  57. #include "conn-ssl.h"
  58. #include "conn-zip.h"
  59. #include "conn-func.h"
  60. #include "log.h"
  61. #include "ng_ipaddr.h"
  62. #include "parse.h"
  63. #include "resolve.h"
  64. #include "tool.h"
  65. #include "exp.h"
  66. #define SERVER_WAIT (NONE - 1)
  67. #define MAX_COMMANDS 3
  68. #define MAX_COMMANDS_SERVER_MIN 10
  69. #define MAX_COMMANDS_SERVICE 10
  70. static bool Handle_Write PARAMS(( CONN_ID Idx ));
  71. static bool Conn_Write PARAMS(( CONN_ID Idx, char *Data, size_t Len ));
  72. static int New_Connection PARAMS(( int Sock, bool IsSSL ));
  73. static CONN_ID Socket2Index PARAMS(( int Sock ));
  74. static void Read_Request PARAMS(( CONN_ID Idx ));
  75. static unsigned int Handle_Buffer PARAMS(( CONN_ID Idx ));
  76. static void Check_Connections PARAMS(( void ));
  77. static void Check_Servers PARAMS(( void ));
  78. static void Init_Conn_Struct PARAMS(( CONN_ID Idx ));
  79. static bool Init_Socket PARAMS(( int Sock ));
  80. static void New_Server PARAMS(( int Server, ng_ipaddr_t *dest ));
  81. static void Simple_Message PARAMS(( int Sock, const char *Msg ));
  82. static int NewListener PARAMS(( const char *listen_addr, UINT16 Port ));
  83. static void Account_Connection PARAMS((void));
  84. static array My_Listeners;
  85. static array My_ConnArray;
  86. static size_t NumConnections, NumConnectionsMax, NumConnectionsAccepted;
  87. #ifdef TCPWRAP
  88. int allow_severity = LOG_INFO;
  89. int deny_severity = LOG_ERR;
  90. #endif
  91. static void server_login PARAMS((CONN_ID idx));
  92. #ifdef SSL_SUPPORT
  93. extern struct SSLOptions Conf_SSLOptions;
  94. static void cb_connserver_login_ssl PARAMS((int sock, short what));
  95. static void cb_clientserver_ssl PARAMS((int sock, short what));
  96. #endif
  97. static void cb_Read_Resolver_Result PARAMS((int sock, UNUSED short what));
  98. static void cb_Connect_to_Server PARAMS((int sock, UNUSED short what));
  99. static void cb_clientserver PARAMS((int sock, short what));
  100. /**
  101. * IO callback for listening sockets: handle new connections. This callback
  102. * gets called when a new non-SSL connection should be accepted.
  103. *
  104. * @param sock Socket descriptor.
  105. * @param irrelevant (ignored IO specification)
  106. */
  107. static void
  108. cb_listen(int sock, short irrelevant)
  109. {
  110. (void) irrelevant;
  111. (void) New_Connection(sock, false);
  112. }
  113. #ifdef SSL_SUPPORT
  114. /**
  115. * IO callback for listening SSL sockets: handle new connections. This callback
  116. * gets called when a new SSL-enabled connection should be accepted.
  117. *
  118. * @param sock Socket descriptor.
  119. * @param irrelevant (ignored IO specification)
  120. */
  121. static void
  122. cb_listen_ssl(int sock, short irrelevant)
  123. {
  124. int fd;
  125. (void) irrelevant;
  126. fd = New_Connection(sock, true);
  127. if (fd < 0)
  128. return;
  129. io_event_setcb(My_Connections[fd].sock, cb_clientserver_ssl);
  130. }
  131. #endif
  132. /**
  133. * IO callback for new outgoing non-SSL server connections.
  134. *
  135. * @param sock Socket descriptor.
  136. * @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...).
  137. */
  138. static void
  139. cb_connserver(int sock, UNUSED short what)
  140. {
  141. int res, err, server;
  142. socklen_t sock_len;
  143. CONN_ID idx = Socket2Index( sock );
  144. if (idx <= NONE) {
  145. LogDebug("cb_connserver wants to write on unknown socket?!");
  146. io_close(sock);
  147. return;
  148. }
  149. assert(what & IO_WANTWRITE);
  150. /* Make sure that the server is still configured; it could have been
  151. * removed in the meantime! */
  152. server = Conf_GetServer(idx);
  153. if (server < 0) {
  154. Log(LOG_ERR, "Connection on socket %d to \"%s\" aborted!",
  155. sock, My_Connections[idx].host);
  156. Conn_Close(idx, "Connection aborted!", NULL, false);
  157. return;
  158. }
  159. /* connect() finished, get result. */
  160. sock_len = (socklen_t)sizeof(err);
  161. res = getsockopt(My_Connections[idx].sock, SOL_SOCKET, SO_ERROR,
  162. &err, &sock_len );
  163. assert(sock_len == sizeof(err));
  164. /* Error while connecting? */
  165. if ((res != 0) || (err != 0)) {
  166. if (res != 0)
  167. Log(LOG_CRIT, "getsockopt (connection %d): %s!",
  168. idx, strerror(errno));
  169. else
  170. Log(LOG_CRIT,
  171. "Can't connect socket to \"%s:%d\" (connection %d): %s!",
  172. My_Connections[idx].host, Conf_Server[server].port,
  173. idx, strerror(err));
  174. Conn_Close(idx, "Can't connect!", NULL, false);
  175. if (ng_ipaddr_af(&Conf_Server[server].dst_addr[0])) {
  176. /* more addresses to try... */
  177. New_Server(server, &Conf_Server[server].dst_addr[0]);
  178. /* connection to dst_addr[0] is now in progress, so
  179. * remove this address... */
  180. Conf_Server[server].dst_addr[0] =
  181. Conf_Server[server].dst_addr[1];
  182. memset(&Conf_Server[server].dst_addr[1], 0,
  183. sizeof(Conf_Server[server].dst_addr[1]));
  184. }
  185. return;
  186. }
  187. /* connect() succeeded, remove all additional addresses */
  188. memset(&Conf_Server[server].dst_addr, 0,
  189. sizeof(Conf_Server[server].dst_addr));
  190. Conn_OPTION_DEL( &My_Connections[idx], CONN_ISCONNECTING );
  191. #ifdef SSL_SUPPORT
  192. if ( Conn_OPTION_ISSET( &My_Connections[idx], CONN_SSL_CONNECT )) {
  193. io_event_setcb( sock, cb_connserver_login_ssl );
  194. io_event_add( sock, IO_WANTWRITE|IO_WANTREAD );
  195. return;
  196. }
  197. #endif
  198. server_login(idx);
  199. }
  200. /**
  201. * Login to a remote server.
  202. *
  203. * @param idx Connection index.
  204. */
  205. static void
  206. server_login(CONN_ID idx)
  207. {
  208. Log(LOG_INFO,
  209. "Connection %d (socket %d) with \"%s:%d\" established. Now logging in ...",
  210. idx, My_Connections[idx].sock, My_Connections[idx].host,
  211. Conf_Server[Conf_GetServer(idx)].port);
  212. io_event_setcb( My_Connections[idx].sock, cb_clientserver);
  213. io_event_add( My_Connections[idx].sock, IO_WANTREAD|IO_WANTWRITE);
  214. /* Send PASS and SERVER command to peer */
  215. Conn_WriteStr( idx, "PASS %s %s", Conf_Server[Conf_GetServer( idx )].pwd_out, NGIRCd_ProtoID );
  216. Conn_WriteStr( idx, "SERVER %s :%s", Conf_ServerName, Conf_ServerInfo );
  217. }
  218. #ifdef SSL_SUPPORT
  219. /**
  220. * IO callback for new outgoing SSL-enabled server connections.
  221. *
  222. * @param sock Socket descriptor.
  223. * @param unused (ignored IO specification)
  224. */
  225. static void
  226. cb_connserver_login_ssl(int sock, short unused)
  227. {
  228. CONN_ID idx = Socket2Index(sock);
  229. assert(idx >= 0);
  230. if (idx < 0) {
  231. io_close(sock);
  232. return;
  233. }
  234. (void) unused;
  235. switch (ConnSSL_Connect( &My_Connections[idx])) {
  236. case 1: break;
  237. case 0: LogDebug("ConnSSL_Connect: not ready");
  238. return;
  239. case -1:
  240. Log(LOG_ERR, "SSL connection on socket %d failed!", sock);
  241. Conn_Close(idx, "Can't connect!", NULL, false);
  242. return;
  243. }
  244. Log( LOG_INFO, "SSL connection %d with \"%s:%d\" established.", idx,
  245. My_Connections[idx].host, Conf_Server[Conf_GetServer( idx )].port );
  246. server_login(idx);
  247. }
  248. #endif
  249. /**
  250. * IO callback for established non-SSL client and server connections.
  251. *
  252. * @param sock Socket descriptor.
  253. * @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...).
  254. */
  255. static void
  256. cb_clientserver(int sock, short what)
  257. {
  258. CONN_ID idx = Socket2Index(sock);
  259. assert(idx >= 0);
  260. if (idx < 0) {
  261. io_close(sock);
  262. return;
  263. }
  264. #ifdef SSL_SUPPORT
  265. if (what & IO_WANTREAD
  266. || (Conn_OPTION_ISSET(&My_Connections[idx], CONN_SSL_WANT_WRITE))) {
  267. /* if TLS layer needs to write additional data, call
  268. * Read_Request() instead so that SSL/TLS can continue */
  269. Read_Request(idx);
  270. }
  271. #else
  272. if (what & IO_WANTREAD)
  273. Read_Request(idx);
  274. #endif
  275. if (what & IO_WANTWRITE)
  276. Handle_Write(idx);
  277. }
  278. #ifdef SSL_SUPPORT
  279. /**
  280. * IO callback for established SSL-enabled client and server connections.
  281. *
  282. * @param sock Socket descriptor.
  283. * @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...).
  284. */
  285. static void
  286. cb_clientserver_ssl(int sock, short what)
  287. {
  288. CONN_ID idx = Socket2Index(sock);
  289. assert(idx >= 0);
  290. if (idx < 0) {
  291. io_close(sock);
  292. return;
  293. }
  294. switch (ConnSSL_Accept(&My_Connections[idx])) {
  295. case 1:
  296. break; /* OK */
  297. case 0:
  298. return; /* EAGAIN: callback will be invoked again by IO layer */
  299. default:
  300. Conn_Close(idx, "SSL accept error, closing socket", "SSL accept error", false);
  301. return;
  302. }
  303. if (what & IO_WANTREAD)
  304. Read_Request(idx);
  305. if (what & IO_WANTWRITE)
  306. Handle_Write(idx);
  307. io_event_setcb(sock, cb_clientserver); /* SSL handshake completed */
  308. }
  309. #endif
  310. /**
  311. * Initialize connecion module.
  312. */
  313. GLOBAL void
  314. Conn_Init( void )
  315. {
  316. CONN_ID i;
  317. /* Speicher fuer Verbindungs-Pool anfordern */
  318. Pool_Size = CONNECTION_POOL;
  319. if ((Conf_MaxConnections > 0) &&
  320. (Pool_Size > Conf_MaxConnections))
  321. Pool_Size = Conf_MaxConnections;
  322. if (!array_alloc(&My_ConnArray, sizeof(CONNECTION), (size_t)Pool_Size)) {
  323. Log(LOG_EMERG, "Can't allocate memory! [Conn_Init]");
  324. exit(1);
  325. }
  326. /* FIXME: My_Connetions/Pool_Size is needed by other parts of the
  327. * code; remove them! */
  328. My_Connections = (CONNECTION*) array_start(&My_ConnArray);
  329. LogDebug("Allocated connection pool for %d items (%ld bytes).",
  330. array_length(&My_ConnArray, sizeof(CONNECTION)),
  331. array_bytes(&My_ConnArray));
  332. assert(array_length(&My_ConnArray, sizeof(CONNECTION)) >= (size_t)Pool_Size);
  333. array_free( &My_Listeners );
  334. for (i = 0; i < Pool_Size; i++)
  335. Init_Conn_Struct(i);
  336. } /* Conn_Init */
  337. /**
  338. * Clean up connection module.
  339. */
  340. GLOBAL void
  341. Conn_Exit( void )
  342. {
  343. CONN_ID idx;
  344. Conn_ExitListeners();
  345. LogDebug("Shutting down all connections ..." );
  346. for( idx = 0; idx < Pool_Size; idx++ ) {
  347. if( My_Connections[idx].sock > NONE ) {
  348. Conn_Close( idx, NULL, NGIRCd_SignalRestart ?
  349. "Server going down (restarting)":"Server going down", true );
  350. }
  351. }
  352. array_free(&My_ConnArray);
  353. My_Connections = NULL;
  354. Pool_Size = 0;
  355. io_library_shutdown();
  356. } /* Conn_Exit */
  357. /**
  358. * Close all sockets (file descriptors) of open connections.
  359. * This is useful in forked child processes, for example, to make sure that
  360. * they don't hold connections open that the main process wants to close.
  361. */
  362. GLOBAL void
  363. Conn_CloseAllSockets(int ExceptOf)
  364. {
  365. CONN_ID idx;
  366. for(idx = 0; idx < Pool_Size; idx++) {
  367. if(My_Connections[idx].sock > NONE &&
  368. My_Connections[idx].sock != ExceptOf)
  369. close(My_Connections[idx].sock);
  370. }
  371. }
  372. /**
  373. * Initialize listening ports.
  374. *
  375. * @param a Array containing the ports the daemon should listen on.
  376. * @param listen_addr Address the socket should listen on (can be "0.0.0.0").
  377. * @param func IO callback function to register.
  378. * @returns Number of listening sockets created.
  379. */
  380. static unsigned int
  381. ports_initlisteners(array *a, const char *listen_addr, void (*func)(int,short))
  382. {
  383. unsigned int created = 0;
  384. size_t len;
  385. int fd;
  386. UINT16 *port;
  387. len = array_length(a, sizeof (UINT16));
  388. port = array_start(a);
  389. while (len--) {
  390. fd = NewListener(listen_addr, *port);
  391. if (fd < 0) {
  392. port++;
  393. continue;
  394. }
  395. if (!io_event_create( fd, IO_WANTREAD, func )) {
  396. Log( LOG_ERR, "io_event_create(): Could not add listening fd %d (port %u): %s!",
  397. fd, (unsigned int) *port, strerror(errno));
  398. close(fd);
  399. port++;
  400. continue;
  401. }
  402. created++;
  403. port++;
  404. }
  405. return created;
  406. }
  407. /**
  408. * Initialize all listening sockets.
  409. *
  410. * @returns Number of created listening sockets
  411. */
  412. GLOBAL unsigned int
  413. Conn_InitListeners( void )
  414. {
  415. /* Initialize ports on which the server should accept connections */
  416. unsigned int created = 0;
  417. char *copy, *listen_addr;
  418. assert(Conf_ListenAddress);
  419. /* can't use Conf_ListenAddress directly, see below */
  420. copy = strdup(Conf_ListenAddress);
  421. if (!copy) {
  422. Log(LOG_CRIT, "Cannot copy %s: %s", Conf_ListenAddress, strerror(errno));
  423. return 0;
  424. }
  425. listen_addr = strtok(copy, ",");
  426. while (listen_addr) {
  427. ngt_TrimStr(listen_addr);
  428. if (*listen_addr) {
  429. created += ports_initlisteners(&Conf_ListenPorts, listen_addr, cb_listen);
  430. #ifdef SSL_SUPPORT
  431. created += ports_initlisteners(&Conf_SSLOptions.ListenPorts, listen_addr, cb_listen_ssl);
  432. #endif
  433. }
  434. listen_addr = strtok(NULL, ",");
  435. }
  436. /* Can't free() Conf_ListenAddress here: on REHASH, if the config file
  437. * cannot be re-loaded, we'd end up with a NULL Conf_ListenAddress.
  438. * Instead, free() takes place in conf.c, before the config file
  439. * is being parsed. */
  440. free(copy);
  441. return created;
  442. } /* Conn_InitListeners */
  443. /**
  444. * Shut down all listening sockets.
  445. */
  446. GLOBAL void
  447. Conn_ExitListeners( void )
  448. {
  449. /* Close down all listening sockets */
  450. int *fd;
  451. size_t arraylen;
  452. arraylen = array_length(&My_Listeners, sizeof (int));
  453. Log(LOG_INFO,
  454. "Shutting down all listening sockets (%d total) ...", arraylen);
  455. fd = array_start(&My_Listeners);
  456. while(arraylen--) {
  457. assert(fd != NULL);
  458. assert(*fd >= 0);
  459. io_close(*fd);
  460. LogDebug("Listening socket %d closed.", *fd );
  461. fd++;
  462. }
  463. array_free(&My_Listeners);
  464. } /* Conn_ExitListeners */
  465. /**
  466. * Bind a socket to a specific (source) address.
  467. *
  468. * @param addr Address structure.
  469. * @param listen_addrstr Source address as string.
  470. * @param Port Port number.
  471. * @returns true on success, false otherwise.
  472. */
  473. static bool
  474. InitSinaddrListenAddr(ng_ipaddr_t *addr, const char *listen_addrstr, UINT16 Port)
  475. {
  476. bool ret;
  477. ret = ng_ipaddr_init(addr, listen_addrstr, Port);
  478. if (!ret) {
  479. assert(listen_addrstr);
  480. Log(LOG_CRIT, "Can't bind to [%s]:%u: can't convert ip address \"%s\"",
  481. listen_addrstr, Port, listen_addrstr);
  482. }
  483. return ret;
  484. }
  485. /**
  486. * Set a socket to "IPv6 only". If the given socket doesn't belong to the
  487. * AF_INET6 family, or the operating system doesn't support this functionality,
  488. * this function retruns silently.
  489. *
  490. * @param af Address family of the socket.
  491. * @param sock Socket handle.
  492. */
  493. static void
  494. set_v6_only(int af, int sock)
  495. {
  496. #if defined(IPV6_V6ONLY) && defined(WANT_IPV6)
  497. int on = 1;
  498. if (af != AF_INET6)
  499. return;
  500. if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, (socklen_t)sizeof(on)))
  501. Log(LOG_ERR, "Could not set IPV6_V6ONLY: %s", strerror(errno));
  502. #else
  503. (void)af;
  504. (void)sock;
  505. #endif
  506. }
  507. /**
  508. * Initialize new listening port.
  509. *
  510. * @param listen_addr Local address to bind the socet to (can be 0.0.0.0).
  511. * @param Port Port number on which the new socket should be listening.
  512. * @returns file descriptor of the socket or -1 on failure.
  513. */
  514. static int
  515. NewListener(const char *listen_addr, UINT16 Port)
  516. {
  517. /* Create new listening socket on specified port */
  518. ng_ipaddr_t addr;
  519. int sock, af;
  520. if (!InitSinaddrListenAddr(&addr, listen_addr, Port))
  521. return -1;
  522. af = ng_ipaddr_af(&addr);
  523. sock = socket(af, SOCK_STREAM, 0);
  524. if( sock < 0 ) {
  525. Log(LOG_CRIT, "Can't create socket (af %d) : %s!", af, strerror(errno));
  526. return -1;
  527. }
  528. set_v6_only(af, sock);
  529. if (!Init_Socket(sock))
  530. return -1;
  531. if (bind(sock, (struct sockaddr *)&addr, ng_ipaddr_salen(&addr)) != 0) {
  532. Log(LOG_CRIT, "Can't bind socket to address %s:%d - %s",
  533. ng_ipaddr_tostr(&addr), Port, strerror(errno));
  534. close(sock);
  535. return -1;
  536. }
  537. if( listen( sock, 10 ) != 0 ) {
  538. Log( LOG_CRIT, "Can't listen on socket: %s!", strerror( errno ));
  539. close( sock );
  540. return -1;
  541. }
  542. /* keep fd in list so we can close it when ngircd restarts/shuts down */
  543. if (!array_catb( &My_Listeners,(char*) &sock, sizeof(int) )) {
  544. Log( LOG_CRIT, "Can't add socket to My_Listeners array: %s!", strerror( errno ));
  545. close( sock );
  546. return -1;
  547. }
  548. Log(LOG_INFO, "Now listening on [%s]:%d (socket %d).",
  549. ng_ipaddr_tostr(&addr), Port, sock);
  550. return sock;
  551. } /* NewListener */
  552. #ifdef SSL_SUPPORT
  553. /**
  554. * Check if SSL library needs to read SSL-protocol related data.
  555. *
  556. * SSL/TLS connections require extra treatment:
  557. * When either CONN_SSL_WANT_WRITE or CONN_SSL_WANT_READ is set, we
  558. * need to take care of that first, before checking read/write buffers.
  559. * For instance, while we might have data in our write buffer, the
  560. * TLS/SSL protocol might need to read internal data first for TLS/SSL
  561. * writes to succeed.
  562. *
  563. * If this function returns true, such a condition is met and we have
  564. * to reverse the condition (check for read even if we've data to write,
  565. * do not check for read but writeability even if write-buffer is empty).
  566. *
  567. * @param c Connection to check.
  568. * @returns true if SSL-library has to read protocol data.
  569. */
  570. static bool
  571. SSL_WantRead(const CONNECTION *c)
  572. {
  573. if (Conn_OPTION_ISSET(c, CONN_SSL_WANT_READ)) {
  574. io_event_add(c->sock, IO_WANTREAD);
  575. return true;
  576. }
  577. return false;
  578. }
  579. /**
  580. * Check if SSL library needs to write SSL-protocol related data.
  581. *
  582. * Please see description of SSL_WantRead() for full description!
  583. *
  584. * @param c Connection to check.
  585. * @returns true if SSL-library has to write protocol data.
  586. */
  587. static bool
  588. SSL_WantWrite(const CONNECTION *c)
  589. {
  590. if (Conn_OPTION_ISSET(c, CONN_SSL_WANT_WRITE)) {
  591. io_event_add(c->sock, IO_WANTWRITE);
  592. return true;
  593. }
  594. return false;
  595. }
  596. #else
  597. static inline bool
  598. SSL_WantRead(UNUSED const CONNECTION *c)
  599. { return false; }
  600. static inline bool
  601. SSL_WantWrite(UNUSED const CONNECTION *c)
  602. { return false; }
  603. #endif
  604. /**
  605. * "Main Loop": Loop until shutdown or restart is signalled.
  606. *
  607. * This function loops until a shutdown or restart of ngIRCd is signalled and
  608. * calls io_dispatch() to check for readable and writable sockets every second.
  609. * It checks for status changes on pending connections (e. g. when a hostname
  610. * has been resolved), checks for "penalties" and timeouts, and handles the
  611. * input buffers.
  612. */
  613. GLOBAL void
  614. Conn_Handler(void)
  615. {
  616. int i;
  617. unsigned int wdatalen, bytes_processed;
  618. struct timeval tv;
  619. time_t t;
  620. while (!NGIRCd_SignalQuit && !NGIRCd_SignalRestart) {
  621. t = time(NULL);
  622. /* Check configured servers and established links */
  623. Check_Servers();
  624. Check_Connections();
  625. /* Expire outdated class/list items */
  626. Class_Expire();
  627. /* Look for non-empty read buffers ... */
  628. for (i = 0; i < Pool_Size; i++) {
  629. if ((My_Connections[i].sock > NONE)
  630. && (array_bytes(&My_Connections[i].rbuf) > 0)
  631. && (My_Connections[i].delaytime <= t)) {
  632. /* ... and try to handle the received data */
  633. bytes_processed = Handle_Buffer(i);
  634. /* if we processed data, and there might be
  635. * more commands in the input buffer, do not
  636. * try to read any more data now */
  637. if (bytes_processed &&
  638. array_bytes(&My_Connections[i].rbuf) > 2) {
  639. LogDebug
  640. ("Throttling connection %d: command limit reached!",
  641. i);
  642. Conn_SetPenalty(i, 1);
  643. }
  644. }
  645. }
  646. /* Look for non-empty write buffers ... */
  647. for (i = 0; i < Pool_Size; i++) {
  648. if (My_Connections[i].sock <= NONE)
  649. continue;
  650. wdatalen = (unsigned int)array_bytes(&My_Connections[i].wbuf);
  651. #ifdef ZLIB
  652. if (wdatalen > 0 ||
  653. array_bytes(&My_Connections[i].zip.wbuf) > 0)
  654. #else
  655. if (wdatalen > 0)
  656. #endif
  657. {
  658. if (SSL_WantRead(&My_Connections[i]))
  659. continue;
  660. io_event_add(My_Connections[i].sock,
  661. IO_WANTWRITE);
  662. }
  663. }
  664. /* Check from which sockets we possibly could read ... */
  665. for (i = 0; i < Pool_Size; i++) {
  666. if (My_Connections[i].sock <= NONE)
  667. continue;
  668. #ifdef SSL_SUPPORT
  669. if (SSL_WantWrite(&My_Connections[i]))
  670. continue; /* TLS/SSL layer needs to write data; deal with this first */
  671. #endif
  672. if (Proc_InProgress(&My_Connections[i].proc_stat)) {
  673. /* Wait for completion of forked subprocess
  674. * and ignore the socket in the meantime ... */
  675. io_event_del(My_Connections[i].sock,
  676. IO_WANTREAD);
  677. continue;
  678. }
  679. if (Conn_OPTION_ISSET(&My_Connections[i], CONN_ISCONNECTING))
  680. /* Wait for completion of connect() ... */
  681. continue;
  682. if (My_Connections[i].delaytime > t) {
  683. /* There is a "penalty time" set: ignore socket! */
  684. io_event_del(My_Connections[i].sock,
  685. IO_WANTREAD);
  686. continue;
  687. }
  688. io_event_add(My_Connections[i].sock, IO_WANTREAD);
  689. }
  690. /* Set the timeout for reading from the network to 1 second,
  691. * which is the granularity with witch we handle "penalty
  692. * times" for example.
  693. * Note: tv_sec/usec are undefined(!) after io_dispatch()
  694. * returns, so we have to set it beforce each call to it! */
  695. tv.tv_usec = 0;
  696. tv.tv_sec = 1;
  697. /* Wait for activity ... */
  698. i = io_dispatch(&tv);
  699. if (i == -1 && errno != EINTR) {
  700. Log(LOG_EMERG, "Conn_Handler(): io_dispatch(): %s!",
  701. strerror(errno));
  702. Log(LOG_ALERT, "%s exiting due to fatal errors!",
  703. PACKAGE_NAME);
  704. exit(1);
  705. }
  706. }
  707. if (NGIRCd_SignalQuit)
  708. Log(LOG_NOTICE | LOG_snotice, "Server going down NOW!");
  709. else if (NGIRCd_SignalRestart)
  710. Log(LOG_NOTICE | LOG_snotice, "Server restarting NOW!");
  711. } /* Conn_Handler */
  712. /**
  713. * Write a text string into the socket of a connection.
  714. *
  715. * This function automatically appends CR+LF to the string and validates that
  716. * the result is a valid IRC message (oversized messages are shortened, for
  717. * example). Then it calls the Conn_Write() function to do the actual sending.
  718. *
  719. * @param Idx Index fo the connection.
  720. * @param Format Format string, see printf().
  721. * @returns true on success, false otherwise.
  722. */
  723. #ifdef PROTOTYPES
  724. GLOBAL bool
  725. Conn_WriteStr(CONN_ID Idx, const char *Format, ...)
  726. #else
  727. GLOBAL bool
  728. Conn_WriteStr(Idx, Format, va_alist)
  729. CONN_ID Idx;
  730. const char *Format;
  731. va_dcl
  732. #endif
  733. {
  734. char buffer[COMMAND_LEN];
  735. #ifdef ICONV
  736. char *ptr, *message;
  737. #endif
  738. size_t len;
  739. bool ok;
  740. va_list ap;
  741. assert( Idx > NONE );
  742. assert( Format != NULL );
  743. #ifdef PROTOTYPES
  744. va_start( ap, Format );
  745. #else
  746. va_start( ap );
  747. #endif
  748. if (vsnprintf( buffer, COMMAND_LEN - 2, Format, ap ) >= COMMAND_LEN - 2 ) {
  749. /*
  750. * The string that should be written to the socket is longer
  751. * than the allowed size of COMMAND_LEN bytes (including both
  752. * the CR and LF characters). This can be caused by the
  753. * IRC_WriteXXX() functions when the prefix of this server had
  754. * to be added to an already "quite long" command line which
  755. * has been received from a regular IRC client, for example.
  756. *
  757. * We are not allowed to send such "oversized" messages to
  758. * other servers and clients, see RFC 2812 2.3 and 2813 3.3
  759. * ("these messages SHALL NOT exceed 512 characters in length,
  760. * counting all characters including the trailing CR-LF").
  761. *
  762. * So we have a big problem here: we should send more bytes
  763. * to the network than we are allowed to and we don't know
  764. * the originator (any more). The "old" behaviour of blaming
  765. * the receiver ("next hop") is a bad idea (it could be just
  766. * an other server only routing the message!), so the only
  767. * option left is to shorten the string and to hope that the
  768. * result is still somewhat useful ...
  769. * -alex-
  770. */
  771. strcpy (buffer + sizeof(buffer) - strlen(CUT_TXTSUFFIX) - 2 - 1,
  772. CUT_TXTSUFFIX);
  773. }
  774. #ifdef ICONV
  775. ptr = strchr(buffer + 1, ':');
  776. if (ptr) {
  777. ptr++;
  778. message = Conn_EncodingTo(Idx, ptr);
  779. if (message != ptr)
  780. strlcpy(ptr, message, sizeof(buffer) - (ptr - buffer));
  781. }
  782. #endif
  783. #ifdef SNIFFER
  784. if (NGIRCd_Sniffer)
  785. Log(LOG_DEBUG, " -> connection %d: '%s'.", Idx, buffer);
  786. #endif
  787. len = strlcat( buffer, "\r\n", sizeof( buffer ));
  788. ok = Conn_Write(Idx, buffer, len);
  789. My_Connections[Idx].msg_out++;
  790. va_end( ap );
  791. return ok;
  792. } /* Conn_WriteStr */
  793. GLOBAL char*
  794. Conn_Password( CONN_ID Idx )
  795. {
  796. assert( Idx > NONE );
  797. if (My_Connections[Idx].pwd == NULL)
  798. return (char*)"\0";
  799. else
  800. return My_Connections[Idx].pwd;
  801. } /* Conn_Password */
  802. GLOBAL void
  803. Conn_SetPassword( CONN_ID Idx, const char *Pwd )
  804. {
  805. assert( Idx > NONE );
  806. if (My_Connections[Idx].pwd)
  807. free(My_Connections[Idx].pwd);
  808. My_Connections[Idx].pwd = strdup(Pwd);
  809. if (My_Connections[Idx].pwd == NULL) {
  810. Log(LOG_EMERG, "Can't allocate memory! [Conn_SetPassword]");
  811. exit(1);
  812. }
  813. } /* Conn_SetPassword */
  814. /**
  815. * Append Data to the outbound write buffer of a connection.
  816. *
  817. * @param Idx Index of the connection.
  818. * @param Data pointer to the data.
  819. * @param Len length of Data.
  820. * @returns true on success, false otherwise.
  821. */
  822. static bool
  823. Conn_Write( CONN_ID Idx, char *Data, size_t Len )
  824. {
  825. CLIENT *c;
  826. size_t writebuf_limit = WRITEBUFFER_MAX_LEN;
  827. assert( Idx > NONE );
  828. assert( Data != NULL );
  829. assert( Len > 0 );
  830. /* Is the socket still open? A previous call to Conn_Write()
  831. * may have closed the connection due to a fatal error.
  832. * In this case it is sufficient to return an error, as well. */
  833. if (My_Connections[Idx].sock <= NONE) {
  834. LogDebug("Skipped write on closed socket (connection %d).", Idx);
  835. return false;
  836. }
  837. /* Make sure that there still exists a CLIENT structure associated
  838. * with this connection and check if this is a server or not: */
  839. c = Conn_GetClient(Idx);
  840. if (c) {
  841. /* Servers do get special write buffer limits, so they can
  842. * generate all the messages that are required while peering. */
  843. if (Client_Type(c) == CLIENT_SERVER)
  844. writebuf_limit = WRITEBUFFER_SLINK_LEN;
  845. } else
  846. LogDebug("Write on socket without client (connection %d)!?", Idx);
  847. #ifdef ZLIB
  848. if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ZIP )) {
  849. /* Compressed link:
  850. * Zip_Buffer() does all the dirty work for us: it flushes
  851. * the (pre-)compression buffers if required and handles
  852. * all error conditions. */
  853. if (!Zip_Buffer(Idx, Data, Len))
  854. return false;
  855. }
  856. else
  857. #endif
  858. {
  859. /* Uncompressed link:
  860. * Check if outbound buffer has enough space for the data. */
  861. if (array_bytes(&My_Connections[Idx].wbuf) + Len >=
  862. WRITEBUFFER_FLUSH_LEN) {
  863. /* Buffer is full, flush it. Handle_Write deals with
  864. * low-level errors, if any. */
  865. if (!Handle_Write(Idx))
  866. return false;
  867. }
  868. /* When the write buffer is still too big after flushing it,
  869. * the connection will be killed. */
  870. if (array_bytes(&My_Connections[Idx].wbuf) + Len >=
  871. writebuf_limit) {
  872. Log(LOG_NOTICE,
  873. "Write buffer space exhausted (connection %d, limit is %lu bytes, %lu bytes new, %lu bytes pending)",
  874. Idx, writebuf_limit, Len,
  875. (unsigned long)array_bytes(&My_Connections[Idx].wbuf));
  876. Conn_Close(Idx, "Write buffer space exhausted", NULL, false);
  877. return false;
  878. }
  879. /* Copy data to write buffer */
  880. if (!array_catb(&My_Connections[Idx].wbuf, Data, Len))
  881. return false;
  882. My_Connections[Idx].bytes_out += Len;
  883. }
  884. /* Adjust global write counter */
  885. WCounter += Len;
  886. return true;
  887. } /* Conn_Write */
  888. /**
  889. * Shut down a connection.
  890. *
  891. * @param Idx Connection index.
  892. * @param LogMsg Message to write to the log or NULL. If no LogMsg
  893. * is given, the FwdMsg is logged.
  894. * @param FwdMsg Message to forward to remote servers.
  895. * @param InformClient If true, inform the client on the connection which is
  896. * to be shut down of the reason (FwdMsg) and send
  897. * connection statistics before disconnecting it.
  898. */
  899. GLOBAL void
  900. Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClient )
  901. {
  902. /* Close connection. Open pipes of asynchronous resolver
  903. * sub-processes are closed down. */
  904. CLIENT *c;
  905. double in_k, out_k;
  906. UINT16 port;
  907. #ifdef ZLIB
  908. double in_z_k, out_z_k;
  909. int in_p, out_p;
  910. #endif
  911. assert( Idx > NONE );
  912. /* Is this link already shutting down? */
  913. if( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ISCLOSING )) {
  914. /* Conn_Close() has been called recursively for this link;
  915. * probabe reason: Handle_Write() failed -- see below. */
  916. LogDebug("Recursive request to close connection: %d", Idx );
  917. return;
  918. }
  919. assert( My_Connections[Idx].sock > NONE );
  920. /* Mark link as "closing" */
  921. Conn_OPTION_ADD( &My_Connections[Idx], CONN_ISCLOSING );
  922. port = ng_ipaddr_getport(&My_Connections[Idx].addr);
  923. Log(LOG_INFO, "Shutting down connection %d (%s) with %s:%d ...", Idx,
  924. LogMsg ? LogMsg : FwdMsg, My_Connections[Idx].host, port);
  925. /* Search client, if any */
  926. c = Conn_GetClient( Idx );
  927. /* Should the client be informed? */
  928. if (InformClient) {
  929. #ifndef STRICT_RFC
  930. /* Send statistics to client if registered as user: */
  931. if ((c != NULL) && (Client_Type(c) == CLIENT_USER)) {
  932. Conn_WriteStr( Idx,
  933. ":%s NOTICE %s :%sConnection statistics: client %.1f kb, server %.1f kb.",
  934. Client_ID(Client_ThisServer()), Client_ID(c),
  935. NOTICE_TXTPREFIX,
  936. (double)My_Connections[Idx].bytes_in / 1024,
  937. (double)My_Connections[Idx].bytes_out / 1024);
  938. }
  939. #endif
  940. /* Send ERROR to client (see RFC 2812, section 3.1.7) */
  941. if (FwdMsg)
  942. Conn_WriteStr(Idx, "ERROR :%s", FwdMsg);
  943. else
  944. Conn_WriteStr(Idx, "ERROR :Closing connection");
  945. }
  946. /* Try to write out the write buffer. Note: Handle_Write() eventually
  947. * removes the CLIENT structure associated with this connection if an
  948. * error occurs! So we have to re-check if there is still an valid
  949. * CLIENT structure after calling Handle_Write() ...*/
  950. (void)Handle_Write( Idx );
  951. /* Search client, if any (re-check!) */
  952. c = Conn_GetClient( Idx );
  953. #ifdef SSL_SUPPORT
  954. if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_SSL )) {
  955. Log(LOG_INFO, "SSL connection %d shutting down ...", Idx);
  956. ConnSSL_Free(&My_Connections[Idx]);
  957. }
  958. #endif
  959. /* Shut down socket */
  960. if (! io_close(My_Connections[Idx].sock)) {
  961. /* Oops, we can't close the socket!? This is ... ugly! */
  962. Log(LOG_CRIT,
  963. "Error closing connection %d (socket %d) with %s:%d - %s! (ignored)",
  964. Idx, My_Connections[Idx].sock, My_Connections[Idx].host,
  965. port, strerror(errno));
  966. }
  967. /* Mark socket as invalid: */
  968. My_Connections[Idx].sock = NONE;
  969. /* If there is still a client, unregister it now */
  970. if (c)
  971. Client_Destroy(c, LogMsg, FwdMsg, true);
  972. /* Calculate statistics and log information */
  973. in_k = (double)My_Connections[Idx].bytes_in / 1024;
  974. out_k = (double)My_Connections[Idx].bytes_out / 1024;
  975. #ifdef ZLIB
  976. if (Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ZIP)) {
  977. in_z_k = (double)My_Connections[Idx].zip.bytes_in / 1024;
  978. out_z_k = (double)My_Connections[Idx].zip.bytes_out / 1024;
  979. /* Make sure that no division by zero can occur during
  980. * the calculation of in_p and out_p: in_z_k and out_z_k
  981. * are non-zero, that's guaranteed by the protocol until
  982. * compression can be enabled. */
  983. if (! in_z_k)
  984. in_z_k = in_k;
  985. if (! out_z_k)
  986. out_z_k = out_k;
  987. in_p = (int)(( in_k * 100 ) / in_z_k );
  988. out_p = (int)(( out_k * 100 ) / out_z_k );
  989. Log(LOG_INFO,
  990. "Connection %d with %s:%d closed (in: %.1fk/%.1fk/%d%%, out: %.1fk/%.1fk/%d%%).",
  991. Idx, My_Connections[Idx].host, port,
  992. in_k, in_z_k, in_p, out_k, out_z_k, out_p);
  993. }
  994. else
  995. #endif
  996. {
  997. Log(LOG_INFO,
  998. "Connection %d with %s:%d closed (in: %.1fk, out: %.1fk).",
  999. Idx, My_Connections[Idx].host, port,
  1000. in_k, out_k);
  1001. }
  1002. /* Servers: Modify time of next connect attempt? */
  1003. Conf_UnsetServer( Idx );
  1004. #ifdef ZLIB
  1005. /* Clean up zlib, if link was compressed */
  1006. if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ZIP )) {
  1007. inflateEnd( &My_Connections[Idx].zip.in );
  1008. deflateEnd( &My_Connections[Idx].zip.out );
  1009. array_free(&My_Connections[Idx].zip.rbuf);
  1010. array_free(&My_Connections[Idx].zip.wbuf);
  1011. }
  1012. #endif
  1013. array_free(&My_Connections[Idx].rbuf);
  1014. array_free(&My_Connections[Idx].wbuf);
  1015. if (My_Connections[Idx].pwd != NULL)
  1016. free(My_Connections[Idx].pwd);
  1017. /* Clean up connection structure (=free it) */
  1018. Init_Conn_Struct( Idx );
  1019. assert(NumConnections > 0);
  1020. if (NumConnections)
  1021. NumConnections--;
  1022. LogDebug("Shutdown of connection %d completed, %ld connection%s left.",
  1023. Idx, NumConnections, NumConnections != 1 ? "s" : "");
  1024. } /* Conn_Close */
  1025. /**
  1026. * Get current number of connections.
  1027. *
  1028. * @returns Number of current connections.
  1029. */
  1030. GLOBAL long
  1031. Conn_Count(void)
  1032. {
  1033. return NumConnections;
  1034. } /* Conn_Count */
  1035. /**
  1036. * Get number of maximum simultaneous connections.
  1037. *
  1038. * @returns Number of maximum simultaneous connections.
  1039. */
  1040. GLOBAL long
  1041. Conn_CountMax(void)
  1042. {
  1043. return NumConnectionsMax;
  1044. } /* Conn_CountMax */
  1045. /**
  1046. * Get number of connections accepted since the daemon startet.
  1047. *
  1048. * @returns Number of connections accepted.
  1049. */
  1050. GLOBAL long
  1051. Conn_CountAccepted(void)
  1052. {
  1053. return NumConnectionsAccepted;
  1054. } /* Conn_CountAccepted */
  1055. /**
  1056. * Synchronize established connections and configured server structures
  1057. * after a configuration update and store the correct connection IDs, if any.
  1058. */
  1059. GLOBAL void
  1060. Conn_SyncServerStruct(void)
  1061. {
  1062. CLIENT *client;
  1063. CONN_ID i;
  1064. int c;
  1065. for (i = 0; i < Pool_Size; i++) {
  1066. if (My_Connections[i].sock == NONE)
  1067. continue;
  1068. /* Server link? */
  1069. client = Conn_GetClient(i);
  1070. if (!client || Client_Type(client) != CLIENT_SERVER)
  1071. continue;
  1072. for (c = 0; c < MAX_SERVERS; c++) {
  1073. /* Configured server? */
  1074. if (!Conf_Server[c].host[0])
  1075. continue;
  1076. if (strcasecmp(Conf_Server[c].name, Client_ID(client)) == 0)
  1077. Conf_Server[c].conn_id = i;
  1078. }
  1079. }
  1080. } /* SyncServerStruct */
  1081. /**
  1082. * Get IP address string of a connection.
  1083. *
  1084. * @param Idx Connection index.
  1085. * @return Pointer to a global buffer containing the IP address as string.
  1086. */
  1087. GLOBAL const char *
  1088. Conn_GetIPAInfo(CONN_ID Idx)
  1089. {
  1090. assert(Idx > NONE);
  1091. return ng_ipaddr_tostr(&My_Connections[Idx].addr);
  1092. }
  1093. /**
  1094. * Send out data of write buffer; connect new sockets.
  1095. *
  1096. * @param Idx Connection index.
  1097. * @returns true on success, false otherwise.
  1098. */
  1099. static bool
  1100. Handle_Write( CONN_ID Idx )
  1101. {
  1102. ssize_t len;
  1103. size_t wdatalen;
  1104. assert( Idx > NONE );
  1105. if ( My_Connections[Idx].sock < 0 ) {
  1106. LogDebug("Handle_Write() on closed socket, connection %d", Idx);
  1107. return false;
  1108. }
  1109. assert( My_Connections[Idx].sock > NONE );
  1110. wdatalen = array_bytes(&My_Connections[Idx].wbuf );
  1111. #ifdef ZLIB
  1112. if (wdatalen == 0) {
  1113. /* Write buffer is empty, so we try to flush the compression
  1114. * buffer and get some data to work with from there :-) */
  1115. if (!Zip_Flush(Idx))
  1116. return false;
  1117. /* Now the write buffer most probably has changed: */
  1118. wdatalen = array_bytes(&My_Connections[Idx].wbuf);
  1119. }
  1120. #endif
  1121. if (wdatalen == 0) {
  1122. /* Still no data, fine. */
  1123. io_event_del(My_Connections[Idx].sock, IO_WANTWRITE );
  1124. return true;
  1125. }
  1126. #ifdef DEBUG_BUFFER
  1127. LogDebug
  1128. ("Handle_Write() called for connection %d, %ld bytes pending ...",
  1129. Idx, wdatalen);
  1130. #endif
  1131. #ifdef SSL_SUPPORT
  1132. if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_SSL )) {
  1133. len = ConnSSL_Write(&My_Connections[Idx], array_start(&My_Connections[Idx].wbuf), wdatalen);
  1134. } else
  1135. #endif
  1136. {
  1137. len = write(My_Connections[Idx].sock,
  1138. array_start(&My_Connections[Idx].wbuf), wdatalen );
  1139. }
  1140. if( len < 0 ) {
  1141. if (errno == EAGAIN || errno == EINTR)
  1142. return true;
  1143. Log(LOG_ERR, "Write error on connection %d (socket %d): %s!",
  1144. Idx, My_Connections[Idx].sock, strerror(errno));
  1145. Conn_Close(Idx, "Write error!", NULL, false);
  1146. return false;
  1147. }
  1148. /* move any data not yet written to beginning */
  1149. array_moveleft(&My_Connections[Idx].wbuf, 1, (size_t)len);
  1150. return true;
  1151. } /* Handle_Write */
  1152. /**
  1153. * Count established connections to a specific IP address.
  1154. *
  1155. * @returns Number of established connections.
  1156. */
  1157. static int
  1158. Count_Connections(ng_ipaddr_t *a)
  1159. {
  1160. int i, cnt;
  1161. cnt = 0;
  1162. for (i = 0; i < Pool_Size; i++) {
  1163. if (My_Connections[i].sock <= NONE)
  1164. continue;
  1165. if (ng_ipaddr_ipequal(&My_Connections[i].addr, a))
  1166. cnt++;
  1167. }
  1168. return cnt;
  1169. } /* Count_Connections */
  1170. /**
  1171. * Initialize new client connection on a listening socket.
  1172. *
  1173. * @param Sock Listening socket descriptor.
  1174. * @param IsSSL true if this socket expects SSL-encrypted data.
  1175. * @returns Accepted socket descriptor or -1 on error.
  1176. */
  1177. static int
  1178. New_Connection(int Sock, UNUSED bool IsSSL)
  1179. {
  1180. #ifdef TCPWRAP
  1181. struct request_info req;
  1182. #endif
  1183. ng_ipaddr_t new_addr;
  1184. char ip_str[NG_INET_ADDRSTRLEN];
  1185. int new_sock, new_sock_len;
  1186. CLIENT *c;
  1187. long cnt;
  1188. assert(Sock > NONE);
  1189. LogDebug("Accepting new connection on socket %d ...", Sock);
  1190. new_sock_len = (int)sizeof(new_addr);
  1191. new_sock = accept(Sock, (struct sockaddr *)&new_addr,
  1192. (socklen_t *)&new_sock_len);
  1193. if (new_sock < 0) {
  1194. Log(LOG_CRIT, "Can't accept connection: %s!", strerror(errno));
  1195. return -1;
  1196. }
  1197. NumConnectionsAccepted++;
  1198. if (!ng_ipaddr_tostr_r(&new_addr, ip_str)) {
  1199. Log(LOG_CRIT, "fd %d: Can't convert IP address!", new_sock);
  1200. Simple_Message(new_sock, "ERROR :Internal Server Error");
  1201. close(new_sock);
  1202. return -1;
  1203. }
  1204. #ifdef TCPWRAP
  1205. /* Validate socket using TCP Wrappers */
  1206. request_init(&req, RQ_DAEMON, PACKAGE_NAME, RQ_FILE, new_sock,
  1207. RQ_CLIENT_SIN, &new_addr, NULL);
  1208. fromhost(&req);
  1209. if (!hosts_access(&req)) {
  1210. Log(deny_severity,
  1211. "Refused connection from %s (by TCP Wrappers)!", ip_str);
  1212. Simple_Message(new_sock, "ERROR :Connection refused");
  1213. close(new_sock);
  1214. return -1;
  1215. }
  1216. #endif
  1217. if (!Init_Socket(new_sock))
  1218. return -1;
  1219. /* Check global connection limit */
  1220. if ((Conf_MaxConnections > 0) &&
  1221. (NumConnections >= (size_t) Conf_MaxConnections)) {
  1222. Log(LOG_ALERT, "Can't accept connection: limit (%d) reached!",
  1223. Conf_MaxConnections);
  1224. Simple_Message(new_sock, "ERROR :Connection limit reached");
  1225. close(new_sock);
  1226. return -1;
  1227. }
  1228. /* Check IP-based connection limit */
  1229. cnt = Count_Connections(&new_addr);
  1230. if ((Conf_MaxConnectionsIP > 0) && (cnt >= Conf_MaxConnectionsIP)) {
  1231. /* Access denied, too many connections from this IP address! */
  1232. Log(LOG_ERR,
  1233. "Refused connection from %s: too may connections (%ld) from this IP address!",
  1234. ip_str, cnt);
  1235. Simple_Message(new_sock,
  1236. "ERROR :Connection refused, too many connections from your IP address");
  1237. close(new_sock);
  1238. return -1;
  1239. }
  1240. if (new_sock >= Pool_Size) {
  1241. if (!array_alloc(&My_ConnArray, sizeof(CONNECTION),
  1242. (size_t) new_sock)) {
  1243. Log(LOG_EMERG,
  1244. "Can't allocate memory! [New_Connection]");
  1245. Simple_Message(new_sock, "ERROR: Internal error");
  1246. close(new_sock);
  1247. return -1;
  1248. }
  1249. LogDebug("Bumped connection pool to %ld items (internal: %ld items, %ld bytes)",
  1250. new_sock, array_length(&My_ConnArray,
  1251. sizeof(CONNECTION)), array_bytes(&My_ConnArray));
  1252. /* Adjust pointer to new block */
  1253. My_Connections = array_start(&My_ConnArray);
  1254. while (Pool_Size <= new_sock)
  1255. Init_Conn_Struct(Pool_Size++);
  1256. }
  1257. /* register callback */
  1258. if (!io_event_create(new_sock, IO_WANTREAD, cb_clientserver)) {
  1259. Log(LOG_ALERT,
  1260. "Can't accept connection: io_event_create failed!");
  1261. Simple_Message(new_sock, "ERROR :Internal error");
  1262. close(new_sock);
  1263. return -1;
  1264. }
  1265. c = Client_NewLocal(new_sock, NULL, CLIENT_UNKNOWN, false);
  1266. if (!c) {
  1267. Log(LOG_ALERT,
  1268. "Can't accept connection: can't create client structure!");
  1269. Simple_Message(new_sock, "ERROR :Internal error");
  1270. io_close(new_sock);
  1271. return -1;
  1272. }
  1273. Init_Conn_Struct(new_sock);
  1274. My_Connections[new_sock].sock = new_sock;
  1275. My_Connections[new_sock].addr = new_addr;
  1276. My_Connections[new_sock].client = c;
  1277. /* Set initial hostname to IP address. This becomes overwritten when
  1278. * the DNS lookup is enabled and succeeds, but is used otherwise. */
  1279. if (ng_ipaddr_af(&new_addr) != AF_INET)
  1280. snprintf(My_Connections[new_sock].host,
  1281. sizeof(My_Connections[new_sock].host), "[%s]", ip_str);
  1282. else
  1283. strlcpy(My_Connections[new_sock].host, ip_str,
  1284. sizeof(My_Connections[new_sock].host));
  1285. Client_SetHostname(c, My_Connections[new_sock].host);
  1286. Log(LOG_INFO, "Accepted connection %d from %s:%d on socket %d.",
  1287. new_sock, My_Connections[new_sock].host,
  1288. ng_ipaddr_getport(&new_addr), Sock);
  1289. Account_Connection();
  1290. #ifdef SSL_SUPPORT
  1291. /* Delay connection initalization until SSL handshake is finished */
  1292. if (!IsSSL)
  1293. #endif
  1294. Conn_StartLogin(new_sock);
  1295. return new_sock;
  1296. } /* New_Connection */
  1297. /**
  1298. * Finish connection initialization, start resolver subprocess.
  1299. *
  1300. * @param Idx Connection index.
  1301. */
  1302. GLOBAL void
  1303. Conn_StartLogin(CONN_ID Idx)
  1304. {
  1305. int ident_sock = -1;
  1306. assert(Idx >= 0);
  1307. /* Nothing to do if DNS (and resolver subprocess) is disabled */
  1308. if (!Conf_DNS)
  1309. return;
  1310. #ifdef IDENTAUTH
  1311. /* Should we make an IDENT request? */
  1312. if (Conf_Ident)
  1313. ident_sock = My_Connections[Idx].sock;
  1314. #endif
  1315. if (Conf_NoticeAuth) {
  1316. /* Send "NOTICE AUTH" messages to the client */
  1317. #ifdef IDENTAUTH
  1318. if (Conf_Ident)
  1319. (void)Conn_WriteStr(Idx,
  1320. "NOTICE AUTH :*** Looking up your hostname and checking ident");
  1321. else
  1322. #endif
  1323. (void)Conn_WriteStr(Idx,
  1324. "NOTICE AUTH :*** Looking up your hostname");
  1325. (void)Handle_Write(Idx);
  1326. }
  1327. Resolve_Addr(&My_Connections[Idx].proc_stat, &My_Connections[Idx].addr,
  1328. ident_sock, cb_Read_Resolver_Result);
  1329. }
  1330. /**
  1331. * Update global connection counters.
  1332. */
  1333. static void
  1334. Account_Connection(void)
  1335. {
  1336. NumConnections++;
  1337. if (NumConnections > NumConnectionsMax)
  1338. NumConnectionsMax = NumConnections;
  1339. LogDebug("Total number of connections now %lu (max %lu).",
  1340. NumConnections, NumConnectionsMax);
  1341. } /* Account_Connection */
  1342. /**
  1343. * Translate socket handle into connection index.
  1344. *
  1345. * @param Sock Socket handle.
  1346. * @returns Connecion index or NONE, if no connection could be found.
  1347. */
  1348. static CONN_ID
  1349. Socket2Index( int Sock )
  1350. {
  1351. assert( Sock >= 0 );
  1352. if( Sock >= Pool_Size || My_Connections[Sock].sock != Sock ) {
  1353. /* the Connection was already closed again, likely due to
  1354. * an error. */
  1355. LogDebug("Socket2Index: can't get connection for socket %d!", Sock);
  1356. return NONE;
  1357. }
  1358. return Sock;
  1359. } /* Socket2Index */
  1360. /**
  1361. * Read data from the network to the read buffer. If an error occures,
  1362. * the socket of this connection will be shut down.
  1363. *
  1364. * @param Idx Connection index.
  1365. */
  1366. static void
  1367. Read_Request( CONN_ID Idx )
  1368. {
  1369. ssize_t len;
  1370. static const unsigned int maxbps = COMMAND_LEN / 2;
  1371. char readbuf[READBUFFER_LEN];
  1372. time_t t;
  1373. CLIENT *c;
  1374. assert( Idx > NONE );
  1375. assert( My_Connections[Idx].sock > NONE );
  1376. #ifdef ZLIB
  1377. if ((array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN) ||
  1378. (array_bytes(&My_Connections[Idx].zip.rbuf) >= READBUFFER_LEN))
  1379. #else
  1380. if (array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN)
  1381. #endif
  1382. {
  1383. /* Read buffer is full */
  1384. Log(LOG_ERR,
  1385. "Receive buffer space exhausted (connection %d): %d bytes",
  1386. Idx, array_bytes(&My_Connections[Idx].rbuf));
  1387. Conn_Close(Idx, "Receive buffer space exhausted", NULL, false);
  1388. return;
  1389. }
  1390. #ifdef SSL_SUPPORT
  1391. if (Conn_OPTION_ISSET(&My_Connections[Idx], CONN_SSL))
  1392. len = ConnSSL_Read( &My_Connections[Idx], readbuf, sizeof(readbuf));
  1393. else
  1394. #endif
  1395. len = read(My_Connections[Idx].sock, readbuf, sizeof(readbuf));
  1396. if (len == 0) {
  1397. Log(LOG_INFO, "%s:%u (%s) is closing the connection ...",
  1398. My_Connections[Idx].host,
  1399. (unsigned int) ng_ipaddr_getport(&My_Connections[Idx].addr),
  1400. ng_ipaddr_tostr(&My_Connections[Idx].addr));
  1401. Conn_Close(Idx,
  1402. "Socket closed!", "Client closed connection",
  1403. false);
  1404. return;
  1405. }
  1406. if (len < 0) {
  1407. if( errno == EAGAIN ) return;
  1408. Log(LOG_ERR, "Read error on connection %d (socket %d): %s!",
  1409. Idx, My_Connections[Idx].sock, strerror(errno));
  1410. Conn_Close(Idx, "Read error!", "Client closed connection",
  1411. false);
  1412. return;
  1413. }
  1414. #ifdef ZLIB
  1415. if (Conn_OPTION_ISSET(&My_Connections[Idx], CONN_ZIP)) {
  1416. if (!array_catb(&My_Connections[Idx].zip.rbuf, readbuf,
  1417. (size_t) len)) {
  1418. Log(LOG_ERR,
  1419. "Could not append received data to zip input buffer (connection %d): %d bytes!",
  1420. Idx, len);
  1421. Conn_Close(Idx, "Receive buffer space exhausted", NULL,
  1422. false);
  1423. return;
  1424. }
  1425. } else
  1426. #endif
  1427. {
  1428. if (!array_catb( &My_Connections[Idx].rbuf, readbuf, len)) {
  1429. Log(LOG_ERR,
  1430. "Could not append received data to input buffer (connection %d): %d bytes!",
  1431. Idx, len);
  1432. Conn_Close(Idx, "Receive buffer space exhausted", NULL, false );
  1433. }
  1434. }
  1435. /* Update connection statistics */
  1436. My_Connections[Idx].bytes_in += len;
  1437. My_Connections[Idx].bps += Handle_Buffer(Idx);
  1438. /* Make sure that there is still a valid client registered */
  1439. c = Conn_GetClient(Idx);
  1440. if (!c)
  1441. return;
  1442. /* Update timestamp of last data received if this connection is
  1443. * registered as a user, server or service connection. Don't update
  1444. * otherwise, so users have at least Conf_PongTimeout seconds time to
  1445. * register with the IRC server -- see Check_Connections().
  1446. * Update "lastping", too, if time shifted backwards ... */
  1447. if (Client_Type(c) == CLIENT_USER
  1448. || Client_Type(c) == CLIENT_SERVER
  1449. || Client_Type(c) == CLIENT_SERVICE) {
  1450. t = time(NULL);
  1451. if (My_Connections[Idx].lastdata != t)
  1452. My_Connections[Idx].bps = 0;
  1453. My_Connections[Idx].lastdata = t;
  1454. if (My_Connections[Idx].lastping > t)
  1455. My_Connections[Idx].lastping = t;
  1456. }
  1457. /* Look at the data in the (read-) buffer of this connection */
  1458. if (Client_Type(c) != CLIENT_SERVER
  1459. && Client_Type(c) != CLIENT_UNKNOWNSERVER
  1460. && Client_Type(c) != CLIENT_SERVICE
  1461. && My_Connections[Idx].bps >= maxbps) {
  1462. LogDebug("Throttling connection %d: BPS exceeded! (%u >= %u)",
  1463. Idx, My_Connections[Idx].bps, maxbps);
  1464. Conn_SetPenalty(Idx, 1);
  1465. }
  1466. } /* Read_Request */
  1467. /**
  1468. * Handle all data in the connection read-buffer.
  1469. *
  1470. * Data is processed until no complete command is left in the read buffer,
  1471. * or MAX_COMMANDS[_SERVER|_SERVICE] commands were processed.
  1472. * When a fatal error occurs, the connection is shut down.
  1473. *
  1474. * @param Idx Index of the connection.
  1475. * @returns Number of bytes processed.
  1476. */
  1477. static unsigned int
  1478. Handle_Buffer(CONN_ID Idx)
  1479. {
  1480. #ifndef STRICT_RFC
  1481. char *ptr1, *ptr2, *first_eol;
  1482. #endif
  1483. char *ptr;
  1484. size_t len, delta;
  1485. time_t starttime;
  1486. #ifdef ZLIB
  1487. bool old_z;
  1488. #endif
  1489. unsigned int i, maxcmd = MAX_COMMANDS, len_processed = 0;
  1490. CLIENT *c;
  1491. c = Conn_GetClient(Idx);
  1492. starttime = time(NULL);
  1493. assert(c != NULL);
  1494. /* Servers get special command limits that depend on the user count */
  1495. switch (Client_Type(c)) {
  1496. case CLIENT_SERVER:
  1497. maxcmd = (int)(Client_UserCount() / 5)
  1498. + MAX_COMMANDS_SERVER_MIN;
  1499. /* Allow servers to handle even more commands while peering
  1500. * to speed up server login and network synchronisation. */
  1501. if (Conn_LastPing(Idx) == 0)
  1502. maxcmd *= 5;
  1503. break;
  1504. case CLIENT_SERVICE:
  1505. maxcmd = MAX_COMMANDS_SERVICE; break;
  1506. }
  1507. for (i=0; i < maxcmd; i++) {
  1508. /* Check penalty */
  1509. if (My_Connections[Idx].delaytime > starttime)
  1510. return 0;
  1511. #ifdef ZLIB
  1512. /* Unpack compressed data, if compression is in use */
  1513. if (Conn_OPTION_ISSET(&My_Connections[Idx], CONN_ZIP)) {
  1514. /* When unzipping fails, Unzip_Buffer() shuts
  1515. * down the connection itself */
  1516. if (!Unzip_Buffer(Idx))
  1517. return 0;
  1518. }
  1519. #endif
  1520. if (0 == array_bytes(&My_Connections[Idx].rbuf))
  1521. break;
  1522. /* Make sure that the buffer is NULL terminated */
  1523. if (!array_cat0_temporary(&My_Connections[Idx].rbuf)) {
  1524. Conn_Close(Idx, NULL,
  1525. "Can't allocate memory [Handle_Buffer]",
  1526. true);
  1527. return 0;
  1528. }
  1529. /* RFC 2812, section "2.3 Messages", 5th paragraph:
  1530. * "IRC messages are always lines of characters terminated
  1531. * with a CR-LF (Carriage Return - Line Feed) pair [...]". */
  1532. delta = 2;
  1533. ptr = strstr(array_start(&My_Connections[Idx].rbuf), "\r\n");
  1534. #ifndef STRICT_RFC
  1535. /* Check for non-RFC-compliant request (only CR or LF)?
  1536. * Unfortunately, there are quite a few clients out there
  1537. * that do this -- e. g. mIRC, BitchX, and Trillian :-( */
  1538. ptr1 = strchr(array_start(&My_Connections[Idx].rbuf), '\r');
  1539. ptr2 = strchr(array_start(&My_Connections[Idx].rbuf), '\n');
  1540. if (ptr) {
  1541. /* Check if there is a single CR or LF _before_ the
  1542. * corerct CR+LF line terminator: */
  1543. first_eol = ptr1 < ptr2 ? ptr1 : ptr2;
  1544. if (first_eol < ptr) {
  1545. /* Single CR or LF before CR+LF found */
  1546. ptr = first_eol;
  1547. delta = 1;
  1548. }
  1549. } else if (ptr1 || ptr2) {
  1550. /* No CR+LF terminated command found, but single
  1551. * CR or LF found ... */
  1552. if (ptr1 && ptr2)
  1553. ptr = ptr1 < ptr2 ? ptr1 : ptr2;
  1554. else
  1555. ptr = ptr1 ? ptr1 : ptr2;
  1556. delta = 1;
  1557. }
  1558. #endif
  1559. if (!ptr)
  1560. break;
  1561. /* Complete (=line terminated) request found, handle it! */
  1562. *ptr = '\0';
  1563. len = ptr - (char *)array_start(&My_Connections[Idx].rbuf) + delta;
  1564. if (len > (COMMAND_LEN - 1)) {
  1565. /* Request must not exceed 512 chars (incl. CR+LF!),
  1566. * see RFC 2812. Disconnect Client if this happens. */
  1567. Log(LOG_ERR,
  1568. "Request too long (connection %d): %d bytes (max. %d expected)!",
  1569. Idx, array_bytes(&My_Connections[Idx].rbuf),
  1570. COMMAND_LEN - 1);
  1571. Conn_Close(Idx, NULL, "Request too long", true);
  1572. return 0;
  1573. }
  1574. len_processed += (unsigned int)len;
  1575. if (len <= delta) {
  1576. /* Request is empty (only '\r\n', '\r' or '\n');
  1577. * delta is 2 ('\r\n') or 1 ('\r' or '\n'), see above */
  1578. array_moveleft(&My_Connections[Idx].rbuf, 1, len);
  1579. continue;
  1580. }
  1581. #ifdef ZLIB
  1582. /* remember if stream is already compressed */
  1583. old_z = My_Connections[Idx].options & CONN_ZIP;
  1584. #endif
  1585. My_Connections[Idx].msg_in++;
  1586. if (!Parse_Request
  1587. (Idx, (char *)array_start(&My_Connections[Idx].rbuf)))
  1588. return 0; /* error -> connection has been closed */
  1589. array_moveleft(&My_Connections[Idx].rbuf, 1, len);
  1590. #ifdef DEBUG_BUFFER
  1591. LogDebug("Connection %d: %d bytes left in read buffer.",
  1592. Idx, array_bytes(&My_Connections[Idx].rbuf));
  1593. #endif
  1594. #ifdef ZLIB
  1595. if ((!old_z) && (My_Connections[Idx].options & CONN_ZIP) &&
  1596. (array_bytes(&My_Connections[Idx].rbuf) > 0)) {
  1597. /* The last command activated socket compression.
  1598. * Data that was read after that needs to be copied
  1599. * to the unzip buffer for decompression: */
  1600. if (!array_copy
  1601. (&My_Connections[Idx].zip.rbuf,
  1602. &My_Connections[Idx].rbuf)) {
  1603. Conn_Close(Idx, NULL,
  1604. "Can't allocate memory [Handle_Buffer]",
  1605. true);
  1606. return 0;
  1607. }
  1608. array_trunc(&My_Connections[Idx].rbuf);
  1609. LogDebug
  1610. ("Moved already received data (%u bytes) to uncompression buffer.",
  1611. array_bytes(&My_Connections[Idx].zip.rbuf));
  1612. }
  1613. #endif
  1614. }
  1615. return len_processed;
  1616. } /* Handle_Buffer */
  1617. /**
  1618. * Check whether established connections are still alive or not.
  1619. * If not, play PING-PONG first; and if that doesn't help either,
  1620. * disconnect the respective peer.
  1621. */
  1622. static void
  1623. Check_Connections(void)
  1624. {
  1625. CLIENT *c;
  1626. CONN_ID i;
  1627. char msg[64];
  1628. for (i = 0; i < Pool_Size; i++) {
  1629. if (My_Connections[i].sock < 0)
  1630. continue;
  1631. c = Conn_GetClient(i);
  1632. if (c && ((Client_Type(c) == CLIENT_USER)
  1633. || (Client_Type(c) == CLIENT_SERVER)
  1634. || (Client_Type(c) == CLIENT_SERVICE))) {
  1635. /* connected User, Server or Service */
  1636. if (My_Connections[i].lastping >
  1637. My_Connections[i].lastdata) {
  1638. /* We already sent a ping */
  1639. if (My_Connections[i].lastping <
  1640. time(NULL) - Conf_PongTimeout) {
  1641. /* Timeout */
  1642. snprintf(msg, sizeof(msg),
  1643. "Ping timeout: %d seconds",
  1644. Conf_PongTimeout);
  1645. LogDebug("Connection %d: %s.", i, msg);
  1646. Conn_Close(i, NULL, msg, true);
  1647. }
  1648. } else if (My_Connections[i].lastdata <
  1649. time(NULL) - Conf_PingTimeout) {
  1650. /* We need to send a PING ... */
  1651. LogDebug("Connection %d: sending PING ...", i);
  1652. Conn_UpdatePing(i);
  1653. Conn_WriteStr(i, "PING :%s",
  1654. Client_ID(Client_ThisServer()));
  1655. }
  1656. } else {
  1657. /* The connection is not fully established yet, so
  1658. * we don't do the PING-PONG game here but instead
  1659. * disconnect the client after "a short time" if it's
  1660. * still not registered. */
  1661. if (My_Connections[i].lastdata <
  1662. time(NULL) - Conf_PongTimeout) {
  1663. LogDebug
  1664. ("Unregistered connection %d timed out ...",
  1665. i);
  1666. Conn_Close(i, NULL, "Timeout", false);
  1667. }
  1668. }
  1669. }
  1670. } /* Check_Connections */
  1671. /**
  1672. * Check if further server links should be established.
  1673. */
  1674. static void
  1675. Check_Servers(void)
  1676. {
  1677. int i, n;
  1678. time_t time_now;
  1679. time_now = time(NULL);
  1680. /* Check all configured servers */
  1681. for (i = 0; i < MAX_SERVERS; i++) {
  1682. if (Conf_Server[i].conn_id != NONE)
  1683. continue; /* Already establishing or connected */
  1684. if (!Conf_Server[i].host[0] || !Conf_Server[i].port > 0)
  1685. continue; /* No host and/or port configured */
  1686. if (Conf_Server[i].flags & CONF_SFLAG_DISABLED)
  1687. continue; /* Disabled configuration entry */
  1688. if (Conf_Server[i].lasttry > (time_now - Conf_ConnectRetry))
  1689. continue; /* We have to wait a little bit ... */
  1690. /* Is there already a connection in this group? */
  1691. if (Conf_Server[i].group > NONE) {
  1692. for (n = 0; n < MAX_SERVERS; n++) {
  1693. if (n == i)
  1694. continue;
  1695. if ((Conf_Server[n].conn_id != NONE) &&
  1696. (Conf_Server[n].group == Conf_Server[i].group))
  1697. break;
  1698. }
  1699. if (n < MAX_SERVERS)
  1700. continue;
  1701. }
  1702. /* Okay, try to connect now */
  1703. Log(LOG_NOTICE,
  1704. "Preparing to establish a new server link for \"%s\" ...",
  1705. Conf_Server[i].name);
  1706. Conf_Server[i].lasttry = time_now;
  1707. Conf_Server[i].conn_id = SERVER_WAIT;
  1708. assert(Proc_GetPipeFd(&Conf_Server[i].res_stat) < 0);
  1709. Resolve_Name(&Conf_Server[i].res_stat, Conf_Server[i].host,
  1710. cb_Connect_to_Server);
  1711. }
  1712. } /* Check_Servers */
  1713. /**
  1714. * Establish a new outgoing server connection.
  1715. *
  1716. * @param Server Configuration index of the server.
  1717. * @param dest Destination IP address to connect to.
  1718. */
  1719. static void
  1720. New_Server( int Server , ng_ipaddr_t *dest)
  1721. {
  1722. /* Establish new server link */
  1723. char ip_str[NG_INET_ADDRSTRLEN];
  1724. int af_dest, res, new_sock;
  1725. CLIENT *c;
  1726. assert( Server > NONE );
  1727. /* Make sure that the remote server hasn't re-linked to this server
  1728. * asynchronously on its own */
  1729. if (Conf_Server[Server].conn_id > NONE) {
  1730. Log(LOG_INFO,
  1731. "Connection to \"%s\" meanwhile re-established, aborting preparation.");
  1732. return;
  1733. }
  1734. if (!ng_ipaddr_tostr_r(dest, ip_str)) {
  1735. Log(LOG_WARNING, "New_Server: Could not convert IP to string");
  1736. return;
  1737. }
  1738. af_dest = ng_ipaddr_af(dest);
  1739. new_sock = socket(af_dest, SOCK_STREAM, 0);
  1740. Log(LOG_INFO,
  1741. "Establishing connection for \"%s\" to \"%s:%d\" (%s), socket %d ...",
  1742. Conf_Server[Server].name, Conf_Server[Server].host,
  1743. Conf_Server[Server].port, ip_str, new_sock);
  1744. if (new_sock < 0) {
  1745. Log(LOG_CRIT, "Can't create socket (af %d): %s!",
  1746. af_dest, strerror(errno));
  1747. return;
  1748. }
  1749. if (!Init_Socket(new_sock))
  1750. return;
  1751. /* is a bind address configured? */
  1752. res = ng_ipaddr_af(&Conf_Server[Server].bind_addr);
  1753. /* if yes, bind now. If it fails, warn and let connect() pick a source address */
  1754. if (res && bind(new_sock, (struct sockaddr *) &Conf_Server[Server].bind_addr,
  1755. ng_ipaddr_salen(&Conf_Server[Server].bind_addr)))
  1756. {
  1757. ng_ipaddr_tostr_r(&Conf_Server[Server].bind_addr, ip_str);
  1758. Log(LOG_WARNING, "Can't bind socket to %s: %s!", ip_str, strerror(errno));
  1759. }
  1760. ng_ipaddr_setport(dest, Conf_Server[Server].port);
  1761. res = connect(new_sock, (struct sockaddr *) dest, ng_ipaddr_salen(dest));
  1762. if(( res != 0 ) && ( errno != EINPROGRESS )) {
  1763. Log( LOG_CRIT, "Can't connect socket: %s!", strerror( errno ));
  1764. close( new_sock );
  1765. return;
  1766. }
  1767. if (!array_alloc(&My_ConnArray, sizeof(CONNECTION), (size_t)new_sock)) {
  1768. Log(LOG_ALERT,
  1769. "Cannot allocate memory for server connection (socket %d)",
  1770. new_sock);
  1771. close( new_sock );
  1772. return;
  1773. }
  1774. if (!io_event_create( new_sock, IO_WANTWRITE, cb_connserver)) {
  1775. Log(LOG_ALERT, "io_event_create(): could not add fd %d", strerror(errno));
  1776. close(new_sock);
  1777. return;
  1778. }
  1779. My_Connections = array_start(&My_ConnArray);
  1780. assert(My_Connections[new_sock].sock <= 0);
  1781. Init_Conn_Struct(new_sock);
  1782. ng_ipaddr_tostr_r(dest, ip_str);
  1783. c = Client_NewLocal(new_sock, ip_str, CLIENT_UNKNOWNSERVER, false);
  1784. if (!c) {
  1785. Log( LOG_ALERT, "Can't establish connection: can't create client structure!" );
  1786. io_close(new_sock);
  1787. return;
  1788. }
  1789. /* Conn_Close() decrements this counter again */
  1790. Account_Connection();
  1791. Client_SetIntroducer( c, c );
  1792. Client_SetToken( c, TOKEN_OUTBOUND );
  1793. /* Register connection */
  1794. if (!Conf_SetServer(Server, new_sock))
  1795. return;
  1796. My_Connections[new_sock].sock = new_sock;
  1797. My_Connections[new_sock].addr = *dest;
  1798. My_Connections[new_sock].client = c;
  1799. strlcpy( My_Connections[new_sock].host, Conf_Server[Server].host,
  1800. sizeof(My_Connections[new_sock].host ));
  1801. #ifdef SSL_SUPPORT
  1802. if (Conf_Server[Server].SSLConnect && !ConnSSL_PrepareConnect( &My_Connections[new_sock],
  1803. &Conf_Server[Server] ))
  1804. {
  1805. Log(LOG_ALERT, "Could not initialize SSL for outgoing connection");
  1806. Conn_Close( new_sock, "Could not initialize SSL for outgoing connection", NULL, false );
  1807. Init_Conn_Struct( new_sock );
  1808. Conf_Server[Server].conn_id = NONE;
  1809. return;
  1810. }
  1811. #endif
  1812. LogDebug("Registered new connection %d on socket %d (%ld in total).",
  1813. new_sock, My_Connections[new_sock].sock, NumConnections);
  1814. Conn_OPTION_ADD( &My_Connections[new_sock], CONN_ISCONNECTING );
  1815. } /* New_Server */
  1816. /**
  1817. * Initialize connection structure.
  1818. *
  1819. * @param Idx Connection index.
  1820. */
  1821. static void
  1822. Init_Conn_Struct(CONN_ID Idx)
  1823. {
  1824. time_t now = time(NULL);
  1825. memset(&My_Connections[Idx], 0, sizeof(CONNECTION));
  1826. My_Connections[Idx].sock = -1;
  1827. My_Connections[Idx].signon = now;
  1828. My_Connections[Idx].lastdata = now;
  1829. My_Connections[Idx].lastprivmsg = now;
  1830. Proc_InitStruct(&My_Connections[Idx].proc_stat);
  1831. #ifdef ICONV
  1832. My_Connections[Idx].iconv_from = (iconv_t)(-1);
  1833. My_Connections[Idx].iconv_to = (iconv_t)(-1);
  1834. #endif
  1835. } /* Init_Conn_Struct */
  1836. /**
  1837. * Initialize options of a new socket.
  1838. *
  1839. * For example, we try to set socket options SO_REUSEADDR and IPTOS_LOWDELAY.
  1840. * The socket is automatically closed if a fatal error is encountered.
  1841. *
  1842. * @param Sock Socket handle.
  1843. * @returns false if socket was closed due to fatal error.
  1844. */
  1845. static bool
  1846. Init_Socket( int Sock )
  1847. {
  1848. int value;
  1849. if (!io_setnonblock(Sock)) {
  1850. Log( LOG_CRIT, "Can't enable non-blocking mode for socket: %s!", strerror( errno ));
  1851. close( Sock );
  1852. return false;
  1853. }
  1854. /* Don't block this port after socket shutdown */
  1855. value = 1;
  1856. if( setsockopt( Sock, SOL_SOCKET, SO_REUSEADDR, &value, (socklen_t)sizeof( value )) != 0 )
  1857. {
  1858. Log( LOG_ERR, "Can't set socket option SO_REUSEADDR: %s!", strerror( errno ));
  1859. /* ignore this error */
  1860. }
  1861. /* Set type of service (TOS) */
  1862. #if defined(IPPROTO_IP) && defined(IPTOS_LOWDELAY)
  1863. value = IPTOS_LOWDELAY;
  1864. if (setsockopt(Sock, IPPROTO_IP, IP_TOS, &value,
  1865. (socklen_t) sizeof(value))) {
  1866. LogDebug("Can't set socket option IP_TOS: %s!",
  1867. strerror(errno));
  1868. /* ignore this error */
  1869. } else
  1870. LogDebug("IP_TOS on socket %d has been set to IPTOS_LOWDELAY.",
  1871. Sock);
  1872. #endif
  1873. return true;
  1874. } /* Init_Socket */
  1875. /**
  1876. * Read results of a resolver sub-process and try to initiate a new server
  1877. * connection.
  1878. *
  1879. * @param fd File descriptor of the pipe to the sub-process.
  1880. * @param events (ignored IO specification)
  1881. */
  1882. static void
  1883. cb_Connect_to_Server(int fd, UNUSED short events)
  1884. {
  1885. /* Read result of resolver sub-process from pipe and start connection */
  1886. int i;
  1887. size_t len;
  1888. ng_ipaddr_t dest_addrs[4]; /* we can handle at most 3; but we read up to
  1889. four so we can log the 'more than we can handle'
  1890. condition. First result is tried immediately, rest
  1891. is saved for later if needed. */
  1892. LogDebug("Resolver: Got forward lookup callback on fd %d, events %d", fd, events);
  1893. for (i=0; i < MAX_SERVERS; i++) {
  1894. if (Proc_GetPipeFd(&Conf_Server[i].res_stat) == fd )
  1895. break;
  1896. }
  1897. if( i >= MAX_SERVERS) {
  1898. /* Ops, no matching server found?! */
  1899. io_close( fd );
  1900. LogDebug("Resolver: Got Forward Lookup callback for unknown server!?");
  1901. return;
  1902. }
  1903. /* Read result from pipe */
  1904. len = Proc_Read(&Conf_Server[i].res_stat, dest_addrs, sizeof(dest_addrs));
  1905. Proc_Close(&Conf_Server[i].res_stat);
  1906. if (len == 0) {
  1907. /* Error resolving hostname: reset server structure */
  1908. Conf_Server[i].conn_id = NONE;
  1909. return;
  1910. }
  1911. assert((len % sizeof(ng_ipaddr_t)) == 0);
  1912. LogDebug("Got result from resolver: %u structs (%u bytes).", len/sizeof(ng_ipaddr_t), len);
  1913. memset(&Conf_Server[i].dst_addr, 0, sizeof(Conf_Server[i].dst_addr));
  1914. if (len > sizeof(ng_ipaddr_t)) {
  1915. /* more than one address for this hostname, remember them
  1916. * in case first address is unreachable/not available */
  1917. len -= sizeof(ng_ipaddr_t);
  1918. if (len > sizeof(Conf_Server[i].dst_addr)) {
  1919. len = sizeof(Conf_Server[i].dst_addr);
  1920. Log(LOG_NOTICE,
  1921. "Notice: Resolver returned more IP Addresses for host than we can handle, additional addresses dropped.");
  1922. }
  1923. memcpy(&Conf_Server[i].dst_addr, &dest_addrs[1], len);
  1924. }
  1925. /* connect() */
  1926. New_Server(i, dest_addrs);
  1927. } /* cb_Read_Forward_Lookup */
  1928. /**
  1929. * Read results of a resolver sub-process from the pipe and update the
  1930. * apropriate connection/client structure(s): hostname and/or IDENT user name.
  1931. *
  1932. * @param r_fd File descriptor of the pipe to the sub-process.
  1933. * @param events (ignored IO specification)
  1934. */
  1935. static void
  1936. cb_Read_Resolver_Result( int r_fd, UNUSED short events )
  1937. {
  1938. CLIENT *c;
  1939. CONN_ID i;
  1940. size_t len;
  1941. char *identptr;
  1942. #ifdef IDENTAUTH
  1943. char readbuf[HOST_LEN + 2 + CLIENT_USER_LEN];
  1944. char *ptr;
  1945. #else
  1946. char readbuf[HOST_LEN + 1];
  1947. #endif
  1948. LogDebug("Resolver: Got callback on fd %d, events %d", r_fd, events );
  1949. i = Conn_GetFromProc(r_fd);
  1950. if (i == NONE) {
  1951. /* Ops, none found? Probably the connection has already
  1952. * been closed!? We'll ignore that ... */
  1953. io_close( r_fd );
  1954. LogDebug("Resolver: Got callback for unknown connection!?");
  1955. return;
  1956. }
  1957. /* Read result from pipe */
  1958. len = Proc_Read(&My_Connections[i].proc_stat, readbuf, sizeof readbuf -1);
  1959. Proc_Close(&My_Connections[i].proc_stat);
  1960. if (len == 0)
  1961. return;
  1962. readbuf[len] = '\0';
  1963. identptr = strchr(readbuf, '\n');
  1964. assert(identptr != NULL);
  1965. if (!identptr) {
  1966. Log( LOG_CRIT, "Resolver: Got malformed result!");
  1967. return;
  1968. }
  1969. *identptr = '\0';
  1970. LogDebug("Got result from resolver: \"%s\" (%u bytes read).", readbuf, len);
  1971. /* Okay, we got a complete result: this is a host name for outgoing
  1972. * connections and a host name and IDENT user name (if enabled) for
  1973. * incoming connections.*/
  1974. assert ( My_Connections[i].sock >= 0 );
  1975. /* Incoming connection. Search client ... */
  1976. c = Conn_GetClient( i );
  1977. assert( c != NULL );
  1978. /* Only update client information of unregistered clients.
  1979. * Note: user commands (e. g. WEBIRC) are always read _after_ reading
  1980. * the resolver results, so we don't have to worry to override settings
  1981. * from these commands here. */
  1982. if(Client_Type(c) == CLIENT_UNKNOWN) {
  1983. strlcpy(My_Connections[i].host, readbuf,
  1984. sizeof(My_Connections[i].host));
  1985. Client_SetHostname(c, readbuf);
  1986. if (Conf_NoticeAuth)
  1987. (void)Conn_WriteStr(i,
  1988. "NOTICE AUTH :*** Found your hostname: %s",
  1989. My_Connections[i].host);
  1990. #ifdef IDENTAUTH
  1991. ++identptr;
  1992. if (*identptr) {
  1993. ptr = identptr;
  1994. while (*ptr) {
  1995. if ((*ptr < '0' || *ptr > '9') &&
  1996. (*ptr < 'A' || *ptr > 'Z') &&
  1997. (*ptr < 'a' || *ptr > 'z'))
  1998. break;
  1999. ptr++;
  2000. }
  2001. if (*ptr) {
  2002. /* Erroneous IDENT reply */
  2003. Log(LOG_NOTICE,
  2004. "Got invalid IDENT reply for connection %d! Ignored.",
  2005. i);
  2006. } else {
  2007. Log(LOG_INFO,
  2008. "IDENT lookup for connection %d: \"%s\".",
  2009. i, identptr);
  2010. Client_SetUser(c, identptr, true);
  2011. }
  2012. if (Conf_NoticeAuth) {
  2013. (void)Conn_WriteStr(i,
  2014. "NOTICE AUTH :*** Got %sident response%s%s",
  2015. *ptr ? "invalid " : "",
  2016. *ptr ? "" : ": ",
  2017. *ptr ? "" : identptr);
  2018. }
  2019. } else {
  2020. Log(LOG_INFO, "IDENT lookup for connection %d: no result.", i);
  2021. if (Conf_NoticeAuth && Conf_Ident)
  2022. (void)Conn_WriteStr(i,
  2023. "NOTICE AUTH :*** No ident response");
  2024. }
  2025. #endif
  2026. if (Conf_NoticeAuth)
  2027. (void)Handle_Write(i);
  2028. Class_HandleServerBans(c);
  2029. }
  2030. #ifdef DEBUG
  2031. else Log( LOG_DEBUG, "Resolver: discarding result for already registered connection %d.", i );
  2032. #endif
  2033. } /* cb_Read_Resolver_Result */
  2034. /**
  2035. * Write a "simple" (error) message to a socket.
  2036. *
  2037. * The message is sent without using the connection write buffers, without
  2038. * compression/encryption, and even without any error reporting. It is
  2039. * designed for error messages of e.g. New_Connection().
  2040. *
  2041. * @param Sock Socket handle.
  2042. * @param Msg Message string to send.
  2043. */
  2044. static void
  2045. Simple_Message(int Sock, const char *Msg)
  2046. {
  2047. char buf[COMMAND_LEN];
  2048. size_t len;
  2049. assert(Sock > NONE);
  2050. assert(Msg != NULL);
  2051. strlcpy(buf, Msg, sizeof buf - 2);
  2052. len = strlcat(buf, "\r\n", sizeof buf);
  2053. if (write(Sock, buf, len) < 0) {
  2054. /* Because this function most probably got called to log
  2055. * an error message, any write error is ignored here to
  2056. * avoid an endless loop. But casting the result of write()
  2057. * to "void" doesn't satisfy the GNU C code attribute
  2058. * "warn_unused_result" which is used by some versions of
  2059. * glibc (e.g. 2.11.1), therefore this silly error
  2060. * "handling" code here :-( */
  2061. return;
  2062. }
  2063. } /* Simple_Error */
  2064. /**
  2065. * Get CLIENT structure that belongs to a local connection identified by its
  2066. * index number. Each connection belongs to a client by definition, so it is
  2067. * not required that the caller checks for NULL return values.
  2068. *
  2069. * @param Idx Connection index number.
  2070. * @returns Pointer to CLIENT structure.
  2071. */
  2072. GLOBAL CLIENT *
  2073. Conn_GetClient( CONN_ID Idx )
  2074. {
  2075. CONNECTION *c;
  2076. assert(Idx >= 0);
  2077. c = array_get(&My_ConnArray, sizeof (CONNECTION), (size_t)Idx);
  2078. assert(c != NULL);
  2079. return c ? c->client : NULL;
  2080. }
  2081. /**
  2082. * Get PROC_STAT sub-process structure of a connection.
  2083. *
  2084. * @param Idx Connection index number.
  2085. * @returns PROC_STAT structure.
  2086. */
  2087. GLOBAL PROC_STAT *
  2088. Conn_GetProcStat(CONN_ID Idx)
  2089. {
  2090. CONNECTION *c;
  2091. assert(Idx >= 0);
  2092. c = array_get(&My_ConnArray, sizeof (CONNECTION), (size_t)Idx);
  2093. assert(c != NULL);
  2094. return &c->proc_stat;
  2095. } /* Conn_GetProcStat */
  2096. /**
  2097. * Get CONN_ID from file descriptor associated to a subprocess structure.
  2098. *
  2099. * @param fd File descriptor.
  2100. * @returns CONN_ID or NONE (-1).
  2101. */
  2102. GLOBAL CONN_ID
  2103. Conn_GetFromProc(int fd)
  2104. {
  2105. int i;
  2106. assert(fd > 0);
  2107. for (i = 0; i < Pool_Size; i++) {
  2108. if ((My_Connections[i].sock != NONE)
  2109. && (Proc_GetPipeFd(&My_Connections[i].proc_stat) == fd))
  2110. return i;
  2111. }
  2112. return NONE;
  2113. } /* Conn_GetFromProc */
  2114. #ifndef STRICT_RFC
  2115. GLOBAL long
  2116. Conn_GetAuthPing(CONN_ID Idx)
  2117. {
  2118. assert (Idx != NONE);
  2119. return My_Connections[Idx].auth_ping;
  2120. } /* Conn_GetAuthPing */
  2121. GLOBAL void
  2122. Conn_SetAuthPing(CONN_ID Idx, long ID)
  2123. {
  2124. assert (Idx != NONE);
  2125. My_Connections[Idx].auth_ping = ID;
  2126. } /* Conn_SetAuthPing */
  2127. #endif
  2128. #ifdef SSL_SUPPORT
  2129. /**
  2130. * Get information about used SSL chiper.
  2131. *
  2132. * @param Idx Connection index number.
  2133. * @param buf Buffer for returned information text.
  2134. * @param len Size of return buffer "buf".
  2135. * @returns true on success, false otherwise.
  2136. */
  2137. GLOBAL bool
  2138. Conn_GetCipherInfo(CONN_ID Idx, char *buf, size_t len)
  2139. {
  2140. if (Idx < 0)
  2141. return false;
  2142. assert(Idx < (int) array_length(&My_ConnArray, sizeof(CONNECTION)));
  2143. return ConnSSL_GetCipherInfo(&My_Connections[Idx], buf, len);
  2144. }
  2145. /**
  2146. * Check if a connection is SSL-enabled or not.
  2147. *
  2148. * @param Idx Connection index number.
  2149. * @return true if connection is SSL-enabled, false otherwise.
  2150. */
  2151. GLOBAL bool
  2152. Conn_UsesSSL(CONN_ID Idx)
  2153. {
  2154. if (Idx < 0)
  2155. return false;
  2156. assert(Idx < (int) array_length(&My_ConnArray, sizeof(CONNECTION)));
  2157. return Conn_OPTION_ISSET(&My_Connections[Idx], CONN_SSL);
  2158. }
  2159. #endif
  2160. #ifdef DEBUG
  2161. /**
  2162. * Dump internal state of the "connection module".
  2163. */
  2164. GLOBAL void
  2165. Conn_DebugDump(void)
  2166. {
  2167. int i;
  2168. Log(LOG_DEBUG, "Connection status:");
  2169. for (i = 0; i < Pool_Size; i++) {
  2170. if (My_Connections[i].sock == NONE)
  2171. continue;
  2172. Log(LOG_DEBUG,
  2173. " - %d: host=%s, lastdata=%ld, lastping=%ld, delaytime=%ld, flag=%d, options=%d, bps=%d, client=%s",
  2174. My_Connections[i].sock, My_Connections[i].host,
  2175. My_Connections[i].lastdata, My_Connections[i].lastping,
  2176. My_Connections[i].delaytime, My_Connections[i].flag,
  2177. My_Connections[i].options, My_Connections[i].bps,
  2178. My_Connections[i].client ? Client_ID(My_Connections[i].client) : "-");
  2179. }
  2180. } /* Conn_DumpClients */
  2181. #endif
  2182. /* -eof- */