You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

lmtp.c 8.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. /*
  2. * Copyright (c) 2009, Rambler media
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY Rambler media ''AS IS'' AND ANY
  14. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  15. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  16. * DISCLAIMED. IN NO EVENT SHALL Rambler BE LIABLE FOR ANY
  17. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  18. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  19. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  20. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  21. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  22. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23. */
  24. #include "config.h"
  25. #include "buffer.h"
  26. #include "main.h"
  27. #include "lmtp.h"
  28. #include "lmtp_proto.h"
  29. #include "cfg_file.h"
  30. #include "url.h"
  31. #include "modules.h"
  32. #include "message.h"
  33. static char greetingbuf[1024];
  34. static struct timeval io_tv;
  35. static void write_socket (void *arg);
  36. static
  37. void sig_handler (int signo)
  38. {
  39. switch (signo) {
  40. case SIGINT:
  41. case SIGTERM:
  42. _exit (1);
  43. break;
  44. }
  45. }
  46. /*
  47. * Config reload is designed by sending sigusr to active workers and pending shutdown of them
  48. */
  49. static void
  50. sigusr_handler (int fd, short what, void *arg)
  51. {
  52. struct rspamd_worker *worker = (struct rspamd_worker *)arg;
  53. /* Do not accept new connections, preparing to end worker's process */
  54. struct timeval tv;
  55. tv.tv_sec = SOFT_SHUTDOWN_TIME;
  56. tv.tv_usec = 0;
  57. event_del (&worker->sig_ev);
  58. event_del (&worker->bind_ev);
  59. do_reopen_log = 1;
  60. msg_info ("worker's shutdown is pending in %d sec", SOFT_SHUTDOWN_TIME);
  61. event_loopexit (&tv);
  62. return;
  63. }
  64. /*
  65. * Destructor for recipients list
  66. */
  67. static void
  68. rcpt_destruct (void *pointer)
  69. {
  70. struct worker_task *task = (struct worker_task *)pointer;
  71. if (task->rcpt) {
  72. g_list_free (task->rcpt);
  73. }
  74. }
  75. /*
  76. * Free all structures of lmtp proto
  77. */
  78. static void
  79. free_task (struct rspamd_lmtp_proto *lmtp)
  80. {
  81. GList *part;
  82. struct mime_part *p;
  83. if (lmtp) {
  84. msg_debug ("free_task: free pointer %p", lmtp->task);
  85. if (lmtp->task->memc_ctx) {
  86. memc_close_ctx (lmtp->task->memc_ctx);
  87. }
  88. while ((part = g_list_first (lmtp->task->parts))) {
  89. lmtp->task->parts = g_list_remove_link (lmtp->task->parts, part);
  90. p = (struct mime_part *)part->data;
  91. g_byte_array_free (p->content, FALSE);
  92. g_list_free_1 (part);
  93. }
  94. memory_pool_delete (lmtp->task->task_pool);
  95. /* Plan dispatcher shutdown */
  96. lmtp->task->dispatcher->wanna_die = 1;
  97. close (lmtp->task->sock);
  98. g_free (lmtp->task);
  99. g_free (lmtp);
  100. }
  101. }
  102. /*
  103. * Callback that is called when there is data to read in buffer
  104. */
  105. static void
  106. read_socket (f_str_t *in, void *arg)
  107. {
  108. struct rspamd_lmtp_proto *lmtp = (struct rspamd_lmtp_proto *)arg;
  109. struct worker_task *task = lmtp->task;
  110. ssize_t r;
  111. switch (task->state) {
  112. case READ_COMMAND:
  113. case READ_HEADER:
  114. if (read_lmtp_input_line (lmtp, in) != 0) {
  115. msg_info ("read_lmtp_socket: closing lmtp connection due to protocol error");
  116. lmtp->task->state = CLOSING_CONNECTION;
  117. }
  118. /* Task was read, recall read handler once more with new state to process message and write reply */
  119. if (task->state == READ_MESSAGE) {
  120. read_socket (in, arg);
  121. }
  122. break;
  123. case READ_MESSAGE:
  124. r = process_message (lmtp->task);
  125. r = process_filters (lmtp->task);
  126. if (r == -1) {
  127. task->last_error = "Filter processing error";
  128. task->error_code = LMTP_FAILURE;
  129. task->state = WRITE_ERROR;
  130. write_socket (lmtp);
  131. }
  132. else if (r == 0) {
  133. task->state = WAIT_FILTER;
  134. rspamd_dispatcher_pause (lmtp->task->dispatcher);
  135. }
  136. else {
  137. process_statfiles (lmtp->task);
  138. task->state = WRITE_REPLY;
  139. write_socket (lmtp);
  140. }
  141. break;
  142. }
  143. }
  144. /*
  145. * Callback for socket writing
  146. */
  147. static void
  148. write_socket (void *arg)
  149. {
  150. struct rspamd_lmtp_proto *lmtp = (struct rspamd_lmtp_proto *)arg;
  151. switch (lmtp->task->state) {
  152. case WRITE_REPLY:
  153. write_lmtp_reply (lmtp);
  154. lmtp->task->state = CLOSING_CONNECTION;
  155. break;
  156. case WRITE_ERROR:
  157. write_lmtp_reply (lmtp);
  158. lmtp->task->state = CLOSING_CONNECTION;
  159. break;
  160. case CLOSING_CONNECTION:
  161. msg_debug ("lmtp_write_socket: normally closing connection");
  162. free_task (lmtp);
  163. break;
  164. }
  165. }
  166. /*
  167. * Called if something goes wrong
  168. */
  169. static void
  170. err_socket (GError *err, void *arg)
  171. {
  172. struct rspamd_lmtp_proto *lmtp = (struct rspamd_lmtp_proto *)arg;
  173. msg_info ("lmtp_err_socket: abnormally closing connection, error: %s", err->message);
  174. /* Free buffers */
  175. free_task (lmtp);
  176. }
  177. /*
  178. * Accept new connection and construct task
  179. */
  180. static void
  181. accept_socket (int fd, short what, void *arg)
  182. {
  183. struct rspamd_worker *worker = (struct rspamd_worker *)arg;
  184. struct sockaddr_storage ss;
  185. struct worker_task *new_task;
  186. struct rspamd_lmtp_proto *lmtp;
  187. socklen_t addrlen = sizeof(ss);
  188. int nfd, on = 1;
  189. struct linger linger;
  190. if ((nfd = accept (fd, (struct sockaddr *)&ss, &addrlen)) == -1) {
  191. return;
  192. }
  193. if (event_make_socket_nonblocking(fd) < 0) {
  194. return;
  195. }
  196. /* Socket options */
  197. setsockopt (nfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on));
  198. setsockopt (nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on));
  199. linger.l_onoff = 1;
  200. linger.l_linger = 2;
  201. setsockopt (nfd, SOL_SOCKET, SO_LINGER, (void *)&linger, sizeof(linger));
  202. lmtp = g_malloc (sizeof (struct rspamd_lmtp_proto));
  203. new_task = g_malloc (sizeof (struct worker_task));
  204. bzero (new_task, sizeof (struct worker_task));
  205. new_task->worker = worker;
  206. new_task->state = READ_COMMAND;
  207. new_task->sock = nfd;
  208. new_task->cfg = worker->srv->cfg;
  209. TAILQ_INIT (&new_task->urls);
  210. new_task->task_pool = memory_pool_new (memory_pool_get_size ());
  211. /* Add destructor for recipients list (it would be better to use anonymous function here */
  212. memory_pool_add_destructor (new_task->task_pool, (pool_destruct_func)rcpt_destruct, new_task);
  213. new_task->results = g_hash_table_new (g_str_hash, g_str_equal);
  214. memory_pool_add_destructor (new_task->task_pool, (pool_destruct_func)g_hash_table_destroy, new_task->results);
  215. worker->srv->stat->connections_count ++;
  216. lmtp->task = new_task;
  217. lmtp->state = LMTP_READ_LHLO;
  218. /* Set up dispatcher */
  219. new_task->dispatcher = rspamd_create_dispatcher (nfd, BUFFER_LINE, read_socket,
  220. write_socket, err_socket, &io_tv,
  221. (void *)lmtp);
  222. rspamd_dispatcher_write (lmtp->task->dispatcher, greetingbuf, strlen (greetingbuf), FALSE);
  223. }
  224. /*
  225. * Start lmtp worker process
  226. */
  227. void
  228. start_lmtp_worker (struct rspamd_worker *worker)
  229. {
  230. struct sigaction signals;
  231. int listen_sock, i;
  232. struct sockaddr_un *un_addr;
  233. char *hostbuf;
  234. long int hostmax;
  235. worker->srv->pid = getpid ();
  236. worker->srv->type = TYPE_LMTP;
  237. event_init ();
  238. g_mime_init (0);
  239. init_signals (&signals, sig_handler);
  240. sigprocmask (SIG_UNBLOCK, &signals.sa_mask, NULL);
  241. /* SIGUSR2 handler */
  242. signal_set (&worker->sig_ev, SIGUSR2, sigusr_handler, (void *) worker);
  243. signal_add (&worker->sig_ev, NULL);
  244. /* Create listen socket */
  245. if (worker->srv->cfg->lmtp_family == AF_INET) {
  246. if ((listen_sock = make_socket (&worker->srv->cfg->lmtp_addr, worker->srv->cfg->lmtp_port)) == -1) {
  247. msg_err ("start_lmtp: cannot create tcp listen socket. %m");
  248. exit(-errno);
  249. }
  250. }
  251. else {
  252. un_addr = (struct sockaddr_un *) alloca (sizeof (struct sockaddr_un));
  253. if (!un_addr || (listen_sock = make_unix_socket (worker->srv->cfg->lmtp_host, un_addr)) == -1) {
  254. msg_err ("start_lmtp: cannot create unix listen socket. %m");
  255. exit(-errno);
  256. }
  257. }
  258. if (listen (listen_sock, -1) == -1) {
  259. msg_err ("start_lmtp: cannot listen on socket. %m");
  260. exit(-errno);
  261. }
  262. /* Accept event */
  263. event_set(&worker->bind_ev, listen_sock, EV_READ | EV_PERSIST, accept_socket, (void *)worker);
  264. event_add(&worker->bind_ev, NULL);
  265. /* Perform modules configuring */
  266. for (i = 0; i < MODULES_NUM; i ++) {
  267. modules[i].module_config_func (worker->srv->cfg);
  268. }
  269. /* Fill hostname buf */
  270. hostmax = sysconf (_SC_HOST_NAME_MAX) + 1;
  271. hostbuf = alloca (hostmax);
  272. gethostname (hostbuf, hostmax);
  273. hostbuf[hostmax - 1] = '\0';
  274. snprintf (greetingbuf, sizeof (greetingbuf), "%d rspamd version %s LMTP on %s Ready\r\n", LMTP_OK, RVERSION, hostbuf);
  275. /* Send SIGUSR2 to parent */
  276. kill (getppid (), SIGUSR2);
  277. io_tv.tv_sec = WORKER_IO_TIMEOUT;
  278. io_tv.tv_usec = 0;
  279. event_loop (0);
  280. }
  281. /*
  282. * vi:ts=4
  283. */