server.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101
  1. /*
  2. * Copyright (C) 1997 Robey Pointer
  3. * Copyright (C) 1999 - 2002 Eggheads Development Team
  4. * Copyright (C) 2002 - 2008 Bryan Drewery
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  19. */
  20. /*
  21. * server.c -- part of server.mod
  22. * basic irc server support
  23. *
  24. */
  25. #include "src/common.h"
  26. #include "src/set.h"
  27. #include "src/botmsg.h"
  28. #include "src/rfc1459.h"
  29. #include "src/settings.h"
  30. #include "src/match.h"
  31. #include "src/binds.h"
  32. #include "src/users.h"
  33. #include "src/userrec.h"
  34. #include "src/main.h"
  35. #include "src/response.h"
  36. #include "src/misc.h"
  37. #include "src/chanprog.h"
  38. #include "src/net.h"
  39. #include "src/auth.h"
  40. #include "src/adns.h"
  41. #include "src/socket.h"
  42. #include "src/egg_timer.h"
  43. #include "src/mod/channels.mod/channels.h"
  44. #include "src/mod/ctcp.mod/ctcp.h"
  45. #include "src/mod/irc.mod/irc.h"
  46. #include <bdlib/src/Stream.h>
  47. #include <bdlib/src/String.h>
  48. #include <bdlib/src/Array.h>
  49. #include "server.h"
  50. #include <stdarg.h>
  51. int default_alines = 5; /* How many mode lines are assumed will work before throttling */
  52. bool floodless = 0; /* floodless iline? */
  53. int ctcp_mode;
  54. int serv = -1; /* sock # of server currently */
  55. int servidx = -1; /* idx of server */
  56. char newserver[121] = ""; /* new server? */
  57. port_t newserverport = 0; /* new server port? */
  58. char newserverpass[121] = ""; /* new server password? */
  59. static char serverpass[121] = "";
  60. static time_t trying_server; /* trying to connect to a server right now? */
  61. int curserv = 999; /* current position in server list: */
  62. port_t curservport = 0;
  63. rate_t flood_msg = { 5, 60 };
  64. rate_t flood_ctcp = { 3, 60 };
  65. char botuserhost[UHOSTLEN] = ""; /* bot's user@host (refreshed whenever the bot joins a channel) */
  66. /* may not be correct user@host BUT it's how the server sees it */
  67. char botuserip[UHOSTLEN] = ""; /* bot's user@host with the ip. */
  68. bool keepnick = 1; /* keep trying to regain my intended
  69. nickname? */
  70. static bool nick_juped = 0; /* True if origbotname is juped(RPL437) (dw) */
  71. static bool jnick_juped = 0; /* True if jupenick is juped */
  72. bool tried_jupenick = 0;
  73. static bool waiting_for_awake; /* set when i unidle myself, cleared when I get the response */
  74. time_t server_online; /* server connection time */
  75. char botrealname[121] = "A deranged product of evil coders."; /* realname of bot */
  76. static interval_t server_timeout = 15; /* server timeout for connecting */
  77. struct server_list *serverlist = NULL; /* old-style queue, still used by
  78. server list */
  79. interval_t cycle_time; /* cycle time till next server connect */
  80. port_t default_port = 6667; /* default IRC port */
  81. bool trigger_on_ignore; /* trigger bindings if user is ignored ? */
  82. int answer_ctcp = 1; /* answer how many stacked ctcp's ? */
  83. static bool check_mode_r; /* check for IRCNET +r modes */
  84. static bool resolvserv; /* in the process of resolving a server host */
  85. static time_t lastpingtime; /* IRCNet LAGmeter support -- drummer */
  86. static char stackablecmds[511] = "";
  87. static char stackable2cmds[511] = "";
  88. static egg_timeval_t last_time;
  89. static time_t connect_bursting = 0;
  90. static int real_msgburst = 0;
  91. static int real_msgrate = 0;
  92. static int flood_count = 0;
  93. static egg_timeval_t flood_time = {0, 0};
  94. static bool use_penalties;
  95. static int use_fastdeq;
  96. size_t nick_len = 9; /* Maximal nick length allowed on the network. */
  97. bool have_cprivmsg = 0;
  98. bool have_cnotice = 0;
  99. static bool double_warned = 0;
  100. static void empty_msgq(void);
  101. static void disconnect_server(int, int);
  102. static void calc_penalty(char *, size_t);
  103. static bool fast_deq(int);
  104. static char *splitnicks(char **);
  105. static void msgq_clear(struct msgq_head *qh);
  106. static int stack_limit = 4;
  107. static bool replaying_cache = 0;
  108. /* New bind tables. */
  109. static bind_table_t *BT_raw = NULL, *BT_msg = NULL;
  110. bind_table_t *BT_ctcr = NULL, *BT_ctcp = NULL, *BT_msgc = NULL;
  111. // Ratbox is (5*8):30, ircd-seven is (5*8):20, try to not push th elimits.
  112. #define SERVER_CONNECT_BURST_TIME 18
  113. #define SERVER_CONNECT_BURST_RATE 5 * 7
  114. #include "servmsg.c"
  115. #define MAXPENALTY 10
  116. /* Maximum messages to store in each queue. */
  117. static struct msgq_head mq, hq, modeq, aq, cacheq;
  118. static const struct {
  119. struct msgq_head* const q;
  120. const int idx;
  121. const char* name;
  122. const char pfx;
  123. const bool double_msg;
  124. const bool burst;
  125. const bool connect_burst;
  126. const size_t maxqmsg;
  127. } qdsc[5] = {
  128. { &modeq, DP_MODE, "MODE", 'm', 0, 1, 1, 300 },
  129. { &mq, DP_SERVER, "SERVER", 's', 0, 1, 1, 300 },
  130. { &hq, DP_HELP, "HELP", 'h', 0, 0, 0, 300 },
  131. { &aq, DP_PLAY, "PLAY", 'p', 1, 1, 0, 10000 },
  132. { &cacheq, DP_CACHE, "CACHE", 'c', 0, 0, 0, 1000 },
  133. };
  134. #define Q_MODE 0
  135. #define Q_SERVER 1
  136. #define Q_HELP 2
  137. #define Q_PLAY 3
  138. #define Q_CACHE 4
  139. static int burst;
  140. #include "cmdsserv.c"
  141. /*
  142. * Bot server queues
  143. */
  144. static bool burst_mode_ok(const char *msg, size_t len) {
  145. bd::String mode(msg, len);
  146. bd::Array<bd::String> list(mode.split(' '));
  147. if (list.length() == 2) return 1;
  148. if (list.length() == 3) {
  149. if (!strchr(CHANMETA, bd::String(list[1]).at(0))) return 1;
  150. else if (bd::String(list[2]).at(0) == 'b') return 1;
  151. }
  152. return 0;
  153. }
  154. static bool burst_ok(const char* msg, size_t len) {
  155. if (strstr(msg, "JOIN 0") ||
  156. (strstr(msg, "MODE") && !burst_mode_ok(msg, len)) ||
  157. strstr(msg, "NICK") ||
  158. strstr(msg, "PRIVMSG") ||
  159. strstr(msg, "NOTICE") ||
  160. strstr(msg, "PART") ||
  161. strstr(msg, "KICK") ||
  162. strstr(msg, "INVITE") ||
  163. strstr(msg, "AWAY")) {
  164. sdprintf("BURST MODE VIOLATION!!!: %s\n", msg);
  165. return 0;
  166. }
  167. return 1;
  168. }
  169. /* Called periodically to shove out another queued item.
  170. *
  171. * 'mode' queue gets priority now.
  172. *
  173. * Most servers will allow 'busts' of upto 5 msgs, so let's put something
  174. * in to support flushing modeq a little faster if possible.
  175. * Will send upto 4 msgs from modeq, and then send 1 msg every time
  176. * it will *not* send anything from hq until the 'burst' value drops
  177. * down to 0 again (allowing a sudden mq flood to sneak through).
  178. *
  179. * ratbox:
  180. * Every msg sent is added to a count, every second this count decreases by 2.
  181. * Typical max count is 20, then excess flood is triggered.
  182. * So after 1 bursts:
  183. * Count = 5
  184. * Decaying by 1 every second
  185. */
  186. void deq_msg()
  187. {
  188. if (serv < 0)
  189. return;
  190. msgrate = 100;
  191. #ifdef DEBUG
  192. if (connect_bursting)
  193. sdprintf("BURSTING!!!!!\n");
  194. #endif
  195. if (timeval_diff(&egg_timeval_now, &flood_time) >= 1000) {
  196. // Increase flood_count by 1 every msg, but decrease by 2 every second, use this to determine an acceptable burst rate
  197. if (flood_count > 1)
  198. flood_count -= 2;
  199. else if (flood_count == 1)
  200. flood_count = 0;
  201. flood_time.sec = egg_timeval_now.sec;
  202. flood_time.usec = egg_timeval_now.usec;
  203. }
  204. /* now < last_time tested 'cause clock adjustments could mess it up */
  205. if (timeval_diff(&egg_timeval_now, &last_time) >= msgrate || now < (last_time.sec - 90)) {
  206. last_time.sec = egg_timeval_now.sec;
  207. last_time.usec = egg_timeval_now.usec;
  208. if (burst > 0) {
  209. if (flood_count < 5)
  210. burst = 0;
  211. else if (flood_count < 10)
  212. burst -= 4;
  213. else if (flood_count < 13)
  214. burst -= 3;
  215. else if (flood_count < 15)
  216. burst -= 2;
  217. else
  218. --burst;
  219. if (burst < 0)
  220. burst = 0;
  221. }
  222. } else
  223. return;
  224. struct msgq *q = NULL;
  225. /* Send upto 'set msgburst' msgs to server if the *critical queue* has anything in it;
  226. * otherwise, dequeue and burst up to 'set msgburst' messages from the `normal' message
  227. * queue.
  228. */
  229. egg_timeval_t last_time_save = { last_time.sec, last_time.usec };
  230. bool bursted = 0;
  231. // -1 here to avoid DP_CACHE
  232. for(size_t nq = 0; nq < (sizeof(qdsc) / sizeof(qdsc[0])) - 1; ++nq) {
  233. while (qdsc[nq].q->head &&
  234. // If burstable queue and can burst, or not a burstable queue and not connect bursting
  235. ((qdsc[nq].burst && (burst < msgburst)) || (!qdsc[nq].burst && !connect_bursting)) &&
  236. ((last_time.sec - now) < MAXPENALTY)) {
  237. #ifdef not_implemented
  238. if (deq_kick(qdsc[nq].idx)) {
  239. ++burst;++flood_count;
  240. continue;
  241. }
  242. #endif
  243. if (fast_deq(nq))
  244. continue;
  245. write_to_server(qdsc[nq].q->head->msg, qdsc[nq].q->head->len);
  246. ++burst;++flood_count;
  247. if (debug_output)
  248. putlog(LOG_SRVOUT, "*", "[%c->] %s", qdsc[nq].pfx, qdsc[nq].q->head->msg);
  249. --(qdsc[nq].q->tot);
  250. calc_penalty(qdsc[nq].q->head->msg, qdsc[nq].q->head->len);
  251. q = qdsc[nq].q->head->next;
  252. free(qdsc[nq].q->head->msg);
  253. free(qdsc[nq].q->head);
  254. qdsc[nq].q->head = q;
  255. if (qdsc[nq].burst)
  256. bursted = 1;
  257. else // Help Queue does not burst, push out 1 line then go to next queue.
  258. break;
  259. }
  260. if (!qdsc[nq].q->head)
  261. qdsc[nq].q->last = NULL;
  262. }
  263. // Do this penalty calc here as it's dependant on burst/flood_count
  264. if (!connect_bursting) {
  265. // The penalty includes a length-based penalty from calc_penalty
  266. last_time.sec -= (msgrate / 1000); // Remove normal msgrate
  267. // Add 150ms for each current burst
  268. last_time.usec += (150*burst) * 1000;
  269. // Add some penalty for each flood_count
  270. last_time.usec += (40*flood_count) * 1000;
  271. // Cap the penalty at 1800 and depent more on flood_count
  272. if (timeval_diff(&last_time, &last_time_save) > 1800) {
  273. last_time.sec = last_time_save.sec;
  274. last_time.usec = 1800 * 1000;
  275. }
  276. #ifdef DEBUG
  277. if (timeval_diff(&last_time, &last_time_save))
  278. sdprintf("PENALTY (%d): %lims", flood_count, timeval_diff(&last_time, &last_time_save));
  279. #endif
  280. }
  281. }
  282. static void calc_penalty(char * msg, size_t len)
  283. {
  284. if (connect_bursting)
  285. return;
  286. char *cmd = NULL, *par1 = NULL, *par2 = NULL, *par3 = NULL;
  287. register int penalty, i, ii;
  288. cmd = newsplit(&msg);
  289. if (msg)
  290. i = strlen(msg);
  291. else
  292. i = strlen(cmd);
  293. if (!use_penalties) {
  294. // Add some penalty for large messages
  295. last_time.usec += ((double)i / 300.0) * (1000*1000);
  296. return;
  297. }
  298. last_time.sec -= (msgrate / 1000); // Remove normal msgrate
  299. penalty = (1 + i / 100);
  300. if (!strcasecmp(cmd, "KICK")) {
  301. par1 = newsplit(&msg); /* channel */
  302. par2 = newsplit(&msg); /* victim(s) */
  303. par3 = splitnicks(&par2);
  304. penalty++;
  305. while (strlen(par3) > 0) {
  306. par3 = splitnicks(&par2);
  307. penalty++;
  308. }
  309. ii = penalty;
  310. par3 = splitnicks(&par1);
  311. while (strlen(par1) > 0) {
  312. par3 = splitnicks(&par1);
  313. penalty += ii;
  314. }
  315. } else if (!strcasecmp(cmd, "MODE")) {
  316. i = 0;
  317. par1 = newsplit(&msg); /* channel */
  318. par2 = newsplit(&msg); /* mode(s) */
  319. if (!strlen(par2))
  320. i++;
  321. while (strlen(par2) > 0) {
  322. if (strchr("ntimps", par2[0]))
  323. i += 3;
  324. else if (!strchr("+-", par2[0]))
  325. i += 1;
  326. par2++;
  327. }
  328. while (strlen(msg) > 0) {
  329. newsplit(&msg);
  330. i += 2;
  331. }
  332. ii = 0;
  333. while (strlen(par1) > 0) {
  334. splitnicks(&par1);
  335. ii++;
  336. }
  337. penalty += (ii * i);
  338. } else if (!strcasecmp(cmd, "TOPIC")) {
  339. penalty++;
  340. par1 = newsplit(&msg); /* channel */
  341. par2 = newsplit(&msg); /* topic */
  342. if (strlen(par2) > 0) { /* topic manipulation => 2 penalty points */
  343. penalty += 2;
  344. par3 = splitnicks(&par1);
  345. while (strlen(par1) > 0) {
  346. par3 = splitnicks(&par1);
  347. penalty += 2;
  348. }
  349. }
  350. } else if (!strcasecmp(cmd, "PRIVMSG") ||
  351. !strcasecmp(cmd, "NOTICE")) {
  352. par1 = newsplit(&msg); /* channel(s)/nick(s) */
  353. /* Add one sec penalty for each recipient */
  354. while (strlen(par1) > 0) {
  355. splitnicks(&par1);
  356. penalty++;
  357. }
  358. } else if (!strcasecmp(cmd, "WHO")) {
  359. par1 = newsplit(&msg); /* masks */
  360. par2 = par1;
  361. while (strlen(par1) > 0) {
  362. par2 = splitnicks(&par1);
  363. if (strlen(par2) > 4) /* long WHO-masks receive less penalty */
  364. penalty += 3;
  365. else
  366. penalty += 5;
  367. }
  368. } else if (!strcasecmp(cmd, "AWAY")) {
  369. if (strlen(msg) > 0)
  370. penalty += 2;
  371. else
  372. penalty += 1;
  373. } else if (!strcasecmp(cmd, "INVITE")) {
  374. /* Successful invite receives 2 or 3 penalty points. Let's go
  375. * with the maximum.
  376. */
  377. penalty += 3;
  378. } else if (!strcasecmp(cmd, "JOIN")) {
  379. penalty += 2;
  380. } else if (!strcasecmp(cmd, "PART")) {
  381. penalty += 4;
  382. } else if (!strcasecmp(cmd, "VERSION")) {
  383. penalty += 2;
  384. } else if (!strcasecmp(cmd, "TIME")) {
  385. penalty += 2;
  386. } else if (!strcasecmp(cmd, "TRACE")) {
  387. penalty += 2;
  388. } else if (!strcasecmp(cmd, "NICK")) {
  389. penalty += 3;
  390. } else if (!strcasecmp(cmd, "ISON")) {
  391. penalty += 1;
  392. } else if (!strcasecmp(cmd, "WHOIS")) {
  393. penalty += 2;
  394. } else if (!strcasecmp(cmd, "DNS")) {
  395. penalty += 2;
  396. } else
  397. penalty++; /* just add standard-penalty */
  398. /* Shouldn't happen, but you never know... */
  399. if (penalty > 99)
  400. penalty = 99;
  401. if (penalty < 2) {
  402. putlog(LOG_SRVOUT, "*", "Penalty < 2sec, that's impossible!");
  403. penalty = 2;
  404. }
  405. if (debug_output && penalty != 0)
  406. putlog(LOG_SRVOUT, "*", "Adding penalty: %i", penalty);
  407. last_time.sec += penalty;
  408. }
  409. char *splitnicks(char **rest)
  410. {
  411. if (!rest)
  412. return *rest = "";
  413. register char *o = *rest, *r = NULL;
  414. while (*o == ' ')
  415. o++;
  416. r = o;
  417. while (*o && *o != ',')
  418. o++;
  419. if (*o)
  420. *o++ = 0;
  421. *rest = o;
  422. return r;
  423. }
  424. void replay_cache(int idx, bd::Stream* stream) {
  425. if (!cacheq.head) return;
  426. struct msgq *r = NULL;
  427. char *p_ptr = NULL, *p = NULL;
  428. replaying_cache = 1;
  429. for (r = cacheq.head; r; r = r->next) {
  430. if (stream) {
  431. bd::String buf;
  432. *stream << buf.printf(STR("+serv_cache %s\n"), r->msg);
  433. } else {
  434. //Create temporary buffer since server_activity may squash the buffer
  435. p_ptr = p = strdup(r->msg);
  436. server_activity(idx, p, r->len);
  437. free(p_ptr);
  438. }
  439. }
  440. replaying_cache = 0;
  441. }
  442. static bool fast_deq(int which)
  443. {
  444. if (!use_fastdeq)
  445. return 0;
  446. struct msgq_head *h = qdsc[which].q;
  447. struct msgq *m = NULL, *nm = NULL;
  448. char msgstr[511] = "", nextmsgstr[511] = "", tosend[511] = "", stackable[511] = "",
  449. *msg = NULL, *nextmsg = NULL, *cmd = NULL, *nextcmd = NULL, *to = NULL, *nextto = NULL, *stckbl = NULL;
  450. int cmd_count = 0;
  451. char stack_delim = ',';
  452. size_t len;
  453. bool found = 0, doit = 0;
  454. bd::String victims;
  455. m = h->head;
  456. strlcpy(msgstr, m->msg, sizeof msgstr);
  457. msg = msgstr;
  458. cmd = newsplit(&msg);
  459. if (use_fastdeq > 1) {
  460. strlcpy(stackable, stackablecmds, sizeof stackable);
  461. stckbl = stackable;
  462. while (strlen(stckbl) > 0)
  463. if (!strcasecmp(newsplit(&stckbl), cmd)) {
  464. found = 1;
  465. break;
  466. }
  467. /* If use_fastdeq is 2, only commands in the list should be stacked. */
  468. if (use_fastdeq == 2 && !found)
  469. return 0;
  470. /* If use_fastdeq is 3, only commands that are _not_ in the list
  471. * should be stacked.
  472. */
  473. if (use_fastdeq == 3 && found)
  474. return 0;
  475. /* we check for the stacking method (default=1) */
  476. strlcpy(stackable, stackable2cmds, sizeof stackable);
  477. stckbl = stackable;
  478. while (strlen(stckbl) > 0)
  479. if (!strcasecmp(newsplit(&stckbl), cmd)) {
  480. stack_delim = ' ';
  481. break;
  482. }
  483. }
  484. to = newsplit(&msg);
  485. len = strlen(to);
  486. victims = to;
  487. while (m) {
  488. nm = m->next;
  489. if (!nm)
  490. break;
  491. strlcpy(nextmsgstr, nm->msg, sizeof nextmsgstr);
  492. nextmsg = nextmsgstr;
  493. nextcmd = newsplit(&nextmsg);
  494. nextto = newsplit(&nextmsg);
  495. len = strlen(nextto);
  496. if ( strcmp(to, nextto) /* we don't stack to the same recipients */
  497. && !strcmp(cmd, nextcmd) && !strcmp(msg, nextmsg)
  498. && ((strlen(cmd) + victims.length() + strlen(nextto)
  499. + strlen(msg) + 2) < 510)
  500. && (!stack_limit || cmd_count < stack_limit - 1)) {
  501. ++cmd_count;
  502. victims += stack_delim + nextto;
  503. doit = 1;
  504. m->next = nm->next;
  505. if (!nm->next)
  506. h->last = m;
  507. free(nm->msg);
  508. free(nm);
  509. --(h->tot);
  510. } else
  511. m = m->next;
  512. }
  513. if (doit) {
  514. len = simple_snprintf(tosend, sizeof(tosend), "%s %s %s", cmd, victims.c_str(), msg);
  515. write_to_server(tosend, len);
  516. ++burst;++flood_count;
  517. m = h->head->next;
  518. free(h->head->msg);
  519. free(h->head);
  520. h->head = m;
  521. if (!h->head)
  522. h->last = 0;
  523. --(h->tot);
  524. if (debug_output)
  525. putlog(LOG_SRVOUT, "*", "[%c=>] %s", qdsc[which].pfx, tosend);
  526. calc_penalty(tosend, len);
  527. return 1;
  528. }
  529. return 0;
  530. }
  531. /* Clean out the msg queues (like when changing servers).
  532. */
  533. static void empty_msgq()
  534. {
  535. for (size_t i = 0; i < (sizeof(qdsc) / sizeof(qdsc[0])); ++i)
  536. msgq_clear(qdsc[i].q);
  537. burst = 0;
  538. flood_count = 0;
  539. flood_time.sec = flood_time.usec = 0;
  540. }
  541. /* Use when sending msgs... will spread them out so there's no flooding.
  542. */
  543. void queue_server(int which, char *buf, int len)
  544. {
  545. /* Don't even BOTHER if there's no server online. */
  546. if (serv < 0)
  547. return;
  548. // If connect bursting, hold off any commands which would end the gracetime (flood_endgrace)
  549. if (connect_bursting && (which == DP_MODE || which == DP_MODE_NEXT || which == DP_SERVER || which == DP_SERVER_NEXT)) {
  550. if (!burst_ok(buf, len))
  551. which = DP_HELP;
  552. }
  553. int qnext = 0;
  554. int which_q = 0;
  555. switch (which) {
  556. case DP_MODE_NEXT:
  557. qnext = 1;
  558. case DP_MODE:
  559. which_q = Q_MODE;
  560. break;
  561. case DP_SERVER_NEXT:
  562. qnext = 1;
  563. case DP_SERVER:
  564. which_q = Q_SERVER;
  565. break;
  566. case DP_HELP_NEXT:
  567. qnext = 1;
  568. case DP_HELP:
  569. which_q = Q_HELP;
  570. break;
  571. case DP_PLAY:
  572. which_q = Q_PLAY;
  573. break;
  574. case DP_CACHE:
  575. which_q = Q_CACHE;
  576. break;
  577. default:
  578. putlog(LOG_MISC, "*", "!!! queuing unknown type to server!!");
  579. return;
  580. }
  581. struct msgq_head *h = qdsc[which_q].q;
  582. if (h->tot < qdsc[which_q].maxqmsg) {
  583. /* Don't queue msg if it's already queued? */
  584. if (!qdsc[which_q].double_msg) {
  585. for (struct msgq* tq = qdsc[which_q].q->head; tq; tq = tq->next) {
  586. if (!strcasecmp(tq->msg, buf)) {
  587. if (!double_warned) {
  588. if (buf[len - 1] == '\n')
  589. buf[len - 1] = 0;
  590. putlog(LOG_DEBUG, "*", "msg already queued. skipping: %s", buf);
  591. double_warned = 1;
  592. }
  593. return;
  594. }
  595. }
  596. }
  597. struct msgq *q = (struct msgq *) my_calloc(1, sizeof(struct msgq));
  598. if (qnext)
  599. q->next = h->head;
  600. else
  601. q->next = NULL;
  602. if (h->head) {
  603. if (!qnext)
  604. h->last->next = q;
  605. } else
  606. h->head = q;
  607. if (qnext)
  608. h->head = q;
  609. h->last = q;
  610. q->len = len;
  611. q->msg = (char *) my_calloc(1, len + 1);
  612. strlcpy(q->msg, buf, len + 1);
  613. h->tot++;
  614. h->warned = 0;
  615. double_warned = 0;
  616. } else {
  617. if (!h->warned)
  618. putlog(LOG_MISC, "*", "!!! OVER MAXIMUM %s QUEUE", qdsc[which_q].name);
  619. h->warned = 1;
  620. }
  621. if (debug_output && !h->warned)
  622. putlog(LOG_SRVOUT, "@", "[%s%c] %s", qnext ? "!!" : "!", qdsc[which_q].pfx, buf);
  623. /* Try flushing immediately */
  624. deq_msg();
  625. }
  626. /* Add a new server to the server_list.
  627. */
  628. void add_server(char *ss)
  629. {
  630. struct server_list *x = NULL, *z = NULL;
  631. char *p = NULL, *q = NULL;
  632. for (z = serverlist; z && z->next; z = z->next)
  633. ;
  634. while (ss) {
  635. p = strchr(ss, ',');
  636. if (p)
  637. *p++ = 0;
  638. x = (struct server_list *) my_calloc(1, sizeof(struct server_list));
  639. x->next = 0;
  640. x->port = 0;
  641. if (z)
  642. z->next = x;
  643. else
  644. serverlist = x;
  645. z = x;
  646. q = strchr(ss, ':');
  647. if (!q) {
  648. x->pass = 0;
  649. x->name = strdup(ss);
  650. } else {
  651. #ifdef USE_IPV6
  652. if (ss[0] == '[') {
  653. ++ss;
  654. q = strchr(ss, ']');
  655. *q++ = 0; /* intentional */
  656. }
  657. #endif /* USE_IPV6 */
  658. *q++ = 0;
  659. x->name = (char *) my_calloc(1, q - ss);
  660. strlcpy(x->name, ss, q - ss);
  661. ss = q;
  662. q = strchr(ss, ':');
  663. if (!q) {
  664. x->pass = 0;
  665. } else {
  666. *q++ = 0;
  667. x->pass = strdup(q);
  668. }
  669. if (!x->port) {
  670. x->port = atoi(ss);
  671. }
  672. }
  673. ss = p;
  674. }
  675. }
  676. /* Clear out the given server_list.
  677. */
  678. void clearq(struct server_list *xx)
  679. {
  680. struct server_list *x = NULL;
  681. while (xx) {
  682. x = xx->next;
  683. if (xx->name)
  684. free(xx->name);
  685. if (xx->pass)
  686. free(xx->pass);
  687. free(xx);
  688. xx = x;
  689. }
  690. }
  691. /* Set botserver to the next available server.
  692. *
  693. * -> if (*ptr == -1) then jump to that particular server
  694. */
  695. void next_server(int *ptr, char *servname, port_t *port, char *pass)
  696. {
  697. struct server_list *x = serverlist;
  698. if (x == NULL)
  699. return;
  700. int i = 0;
  701. /* -1 --> Go to specified server */
  702. if (*ptr == (-1)) {
  703. for (; x; x = x->next) {
  704. if (x->port == *port) {
  705. if (!strcasecmp(x->name, servname)) {
  706. *ptr = i;
  707. return;
  708. }
  709. }
  710. i++;
  711. }
  712. /* Gotta add it: */
  713. x = (struct server_list *) my_calloc(1, sizeof(struct server_list));
  714. x->next = 0;
  715. x->name = strdup(servname);
  716. x->port = *port ? *port : default_port;
  717. if (pass && pass[0]) {
  718. x->pass = strdup(pass);
  719. } else
  720. x->pass = NULL;
  721. list_append((struct list_type **) (&serverlist), (struct list_type *) x);
  722. *ptr = i;
  723. return;
  724. }
  725. /* Find where i am and boogie */
  726. i = (*ptr);
  727. while (i > 0 && x != NULL) {
  728. x = x->next;
  729. i--;
  730. }
  731. if (x != NULL) {
  732. x = x->next;
  733. (*ptr)++;
  734. } /* Go to next server */
  735. if (x == NULL) {
  736. x = serverlist;
  737. *ptr = 0;
  738. } /* Start over at the beginning */
  739. strcpy(servname, x->name);
  740. *port = x->port ? x->port : default_port;
  741. if (x->pass)
  742. strcpy(pass, x->pass);
  743. else
  744. pass[0] = 0;
  745. }
  746. /*
  747. * CTCP DCC CHAT functions
  748. */
  749. static int sanitycheck_dcc(char *nick, char *from, char *ipaddy, char *port)
  750. {
  751. /* According to the latest RFC, the clients SHOULD be able to handle
  752. * DNS names that are up to 255 characters long. This is not broken.
  753. */
  754. char badaddress[16];
  755. in_addr_t ip = my_atoul(ipaddy);
  756. int prt = atoi(port);
  757. if (prt < 1) {
  758. putlog(LOG_MISC, "*", "ALERT: (%s!%s) specified an impossible port of %u!",
  759. nick, from, prt);
  760. return 0;
  761. }
  762. simple_snprintf(badaddress, sizeof(badaddress), "%u.%u.%u.%u", (ip >> 24) & 0xff, (ip >> 16) & 0xff,
  763. (ip >> 8) & 0xff, ip & 0xff);
  764. if (ip < (1 << 24)) {
  765. putlog(LOG_MISC, "*", "ALERT: (%s!%s) specified an impossible IP of %s!",
  766. nick, from, badaddress);
  767. return 0;
  768. }
  769. return 1;
  770. }
  771. static void dcc_chat_hostresolved(int);
  772. /* This only handles CHAT requests, otherwise it's handled in filesys.
  773. */
  774. static int ctcp_DCC_CHAT(char *nick, char *from, struct userrec *u, char *object, char *keyword, char *text)
  775. {
  776. if (!ischanhub())
  777. return BIND_RET_LOG;
  778. char *action = NULL, *param = NULL, *ip = NULL, *prt = NULL;
  779. action = newsplit(&text);
  780. param = newsplit(&text);
  781. ip = newsplit(&text);
  782. prt = newsplit(&text);
  783. if (strcasecmp(action, "CHAT") || strcasecmp(object, botname) || !u)
  784. return BIND_RET_LOG;
  785. int i;
  786. bool ok = 1;
  787. struct flag_record fr = {FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0 };
  788. get_user_flagrec(u, &fr, NULL);
  789. if (ischanhub() && !glob_chuba(fr))
  790. ok = 0;
  791. if (dcc_total == max_dcc) {
  792. putlog(LOG_MISC, "*", "DCC connections full: %s %s (%s!%s)", "CHAT", param, nick, from);
  793. } else if (!ok) {
  794. putlog(LOG_MISC, "*", "%s: %s!%s", ischanhub() ? "Refused DCC chat (no access)" : "Refused DCC chat (I'm not a chathub (+c))", nick, from);
  795. } else if (u_pass_match(u, "-")) {
  796. putlog(LOG_MISC, "*", "%s: %s!%s", "Refused DCC chat (no password)", nick, from);
  797. } else if (atoi(prt) < 1024 || atoi(prt) > 65535) {
  798. /* Invalid port */
  799. putlog(LOG_MISC, "*", "%s: CHAT (%s!%s)", "DCC invalid port", nick, from);
  800. } else {
  801. if (!sanitycheck_dcc(nick, from, ip, prt))
  802. return 1;
  803. i = new_dcc(&DCC_CHAT_PASS, sizeof(struct chat_info));
  804. if (i < 0) {
  805. putlog(LOG_MISC, "*", "DCC connection: CHAT (%s!%s)", nick, ip);
  806. return BIND_RET_BREAK;
  807. }
  808. dcc[i].addr = my_atoul(ip);
  809. dcc[i].port = atoi(prt);
  810. dcc[i].sock = -1;
  811. strlcpy(dcc[i].nick, u->handle, NICKLEN);
  812. strlcpy(dcc[i].host, from, UHOSTLEN);
  813. dcc[i].timeval = now;
  814. dcc[i].user = u;
  815. dcc_chat_hostresolved(i);
  816. // egg_dns_reverse(dcc[i].addr, 20, dcc_chat_dns_callback, (void *) i);
  817. }
  818. return BIND_RET_BREAK;
  819. }
  820. //static void tandem_relay_dns_callback(void *client_data, const char *host, char **ips)
  821. static void dcc_chat_hostresolved(int i)
  822. {
  823. char buf[512] = "", ip[512] = "";
  824. struct flag_record fr = {FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0 };
  825. simple_snprintf(buf, sizeof buf, "%d", dcc[i].port);
  826. simple_snprintf(ip, sizeof ip, "%lu", (0xffffffff & ((long) dcc[i].addr)));
  827. #ifdef USE_IPV6
  828. dcc[i].sock = getsock(0, AF_INET);
  829. #else
  830. dcc[i].sock = getsock(0);
  831. #endif /* USE_IPV6 */
  832. int open_telnet_return = 0;
  833. if (dcc[i].sock < 0 || (open_telnet_return = open_telnet_dcc(dcc[i].sock, ip, buf)) < 0) {
  834. if (open_telnet_return == -1)
  835. dcc[i].sock = -1;
  836. strlcpy(buf, strerror(errno), sizeof(buf));
  837. putlog(LOG_MISC, "*", "%s: CHAT (%s!%s)", "DCC connection failed", dcc[i].nick, dcc[i].host);
  838. putlog(LOG_MISC, "*", " (%s)", buf);
  839. if (dcc[i].sock != -1)
  840. killsock(dcc[i].sock);
  841. lostdcc(i);
  842. } else {
  843. bool ok = 1;
  844. dcc[i].status = STAT_ECHO;
  845. get_user_flagrec(dcc[i].user, &fr, NULL);
  846. if (ischanhub() && !glob_chuba(fr))
  847. ok = 0;
  848. if (ok)
  849. dcc[i].status |= STAT_PARTY;
  850. struct chat_info dummy;
  851. strlcpy(dcc[i].u.chat->con_chan, (chanset) ? chanset->dname : "*", sizeof(dummy.con_chan));
  852. dcc[i].timeval = now;
  853. /* Ok, we're satisfied with them now: attempt the connect */
  854. putlog(LOG_MISC, "*", "DCC connection: CHAT (%s!%s)", dcc[i].nick, dcc[i].host);
  855. dprintf(i, "%s\n", response(RES_USERNAME));
  856. }
  857. return;
  858. }
  859. /*
  860. * Server timer functions
  861. */
  862. static void end_burstmode() {
  863. if (connect_bursting) {
  864. connect_bursting = 0;
  865. msgburst = real_msgburst;
  866. msgrate = real_msgrate;
  867. }
  868. }
  869. static void server_secondly()
  870. {
  871. if (cycle_time)
  872. --cycle_time;
  873. if (!resolvserv && serv < 0 && !trying_server)
  874. connect_server();
  875. if (connect_bursting && server_online && (now - SERVER_CONNECT_BURST_TIME) >= connect_bursting) {
  876. end_burstmode();
  877. putlog(LOG_DEBUG, "*", "Ending server burst mode");
  878. }
  879. }
  880. static void server_check_lag()
  881. {
  882. if (server_online && !waiting_for_awake && !trying_server) {
  883. dprintf(DP_MODE_NEXT, "PING :%li\n", (long)now);
  884. lastpingtime = now;
  885. waiting_for_awake = 1;
  886. }
  887. }
  888. static void server_5minutely()
  889. {
  890. if (server_online && waiting_for_awake && ((now - lastpingtime) >= 300)) {
  891. /* Uh oh! Never got pong from last time, five minutes ago!
  892. * Server is probably stoned.
  893. */
  894. disconnect_server(servidx, DO_LOST);
  895. putlog(LOG_SERV, "*", "Server got stoned; jumping...");
  896. }
  897. }
  898. void server_die()
  899. {
  900. cycle_time = 100;
  901. if (server_online) {
  902. dprintf(-serv, "QUIT :%s\n", quit_msg[0] ? quit_msg : "");
  903. sleep(2); /* Give the server time to understand */
  904. }
  905. nuke_server(NULL);
  906. }
  907. /* A report on the module status.
  908. */
  909. void server_report(int idx, int details)
  910. {
  911. char s1[64] = "", s[128] = "";
  912. if (server_online) {
  913. dprintf(idx, " Online as: %s%s%s (%s)\n", botname,
  914. botuserhost[0] ? "!" : "", botuserhost[0] ? botuserhost : "",
  915. botrealname);
  916. dprintf(idx, " My userip: %s!%s\n", botname, botuserip);
  917. if (nick_juped)
  918. dprintf(idx, " NICK IS JUPED: %s %s\n", origbotname, keepnick ? "(trying)" : "");
  919. if (jnick_juped)
  920. dprintf(idx, " JUPENICK IS JUPED: %s %s\n", jupenick, keepnick ? "(trying)" : "");
  921. nick_juped = jnick_juped = 0;
  922. daysdur(now, server_online, s1, sizeof(s1));
  923. simple_snprintf(s, sizeof s, "(connected %s)", s1);
  924. if (server_lag && !waiting_for_awake) {
  925. if (server_lag == (-1))
  926. simple_snprintf(s1, sizeof s1, " (bad pong replies)");
  927. else
  928. simple_snprintf(s1, sizeof s1, " (lag: %ds)", server_lag);
  929. strlcat(s, s1, sizeof(s));
  930. }
  931. }
  932. if ((trying_server || server_online) && (servidx != (-1))) {
  933. dprintf(idx, " Server %s:%d %s\n", dcc[servidx].host, dcc[servidx].port,
  934. trying_server ? "(trying)" : s);
  935. } else
  936. dprintf(idx, " No server currently.\n");
  937. if (server_online)
  938. dprintf(idx, " burst: %d flood_count: %d\n", burst, flood_count);
  939. for (size_t i = 0; i < (sizeof(qdsc) / sizeof(qdsc[0])); ++i) {
  940. if (qdsc[i].q->tot)
  941. dprintf(idx, " %s queue is at %d%%, %d msgs\n",
  942. qdsc[i].name,
  943. (int) ((float) (qdsc[i].q->tot * 100.0) / (float) qdsc[i].maxqmsg),
  944. (int) qdsc[i].q->tot);
  945. }
  946. if (details) {
  947. dprintf(idx, " Flood is: %d msg/%ds, %d ctcp/%ds\n",
  948. flood_msg.count, flood_msg.time, flood_ctcp.count, flood_ctcp.time);
  949. }
  950. }
  951. static void msgq_clear(struct msgq_head *qh)
  952. {
  953. register struct msgq *qq = NULL;
  954. for (register struct msgq *q = qh->head; q; q = qq) {
  955. qq = q->next;
  956. free(q->msg);
  957. free(q);
  958. }
  959. qh->head = qh->last = NULL;
  960. qh->tot = qh->warned = 0;
  961. }
  962. static cmd_t my_ctcps[] =
  963. {
  964. {"DCC", "", (Function) ctcp_DCC_CHAT, "server:DCC", LEAF},
  965. {NULL, NULL, NULL, NULL, 0}
  966. };
  967. void server_init()
  968. {
  969. strlcpy(botrealname, "A deranged product of evil coders", sizeof(botrealname));
  970. strlcpy(stackable2cmds, "USERHOST ISON", sizeof(stackable2cmds));
  971. /*
  972. * Init of all the variables *must* be done in _start rather than
  973. * globally.
  974. */
  975. BT_msgc = bind_table_add("msgc", 3, "Ass", MATCH_FLAGS, 0); // Auth, chname, par
  976. BT_msg = bind_table_add("msg", 4, "ssUs", MATCH_FLAGS, 0);
  977. BT_raw = bind_table_add("raw", 2, "ss", 0, BIND_STACKABLE);
  978. BT_ctcr = bind_table_add("ctcr", 6, "ssUsss", 0, BIND_STACKABLE);
  979. BT_ctcp = bind_table_add("ctcp", 6, "ssUsss", 0, BIND_STACKABLE);
  980. add_builtins("raw", my_raw_binds);
  981. add_builtins("dcc", C_dcc_serv);
  982. add_builtins("ctcp", my_ctcps);
  983. egg_timeval_t howlong;
  984. howlong.sec = 0;
  985. howlong.usec = 200 * 1000;
  986. timer_create_repeater(&howlong, "server_queue", (Function) deq_msg);
  987. timer_create_secs(1, "server_secondly", (Function) server_secondly);
  988. timer_create_secs(30, "server_check_lag", (Function) server_check_lag);
  989. timer_create_secs(300, "server_5minutely", (Function) server_5minutely);
  990. timer_create_secs(60, "minutely_checks", (Function) minutely_checks);
  991. }