GNUnet  0.10.x
plugin_transport_smtp.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2003-2013 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
28 #include "platform.h"
29 #include "gnunet_util.h"
30 #include "gnunet_constants.h"
31 #include "gnunet_protocols.h"
32 #include "gnunet_transport.h"
33 #include "gnunet_stats_service.h"
34 #include <libesmtp.h>
35 #include <signal.h>
36 
37 
41 #define SMTP_MESSAGE_SIZE 65528
42 
43 #define DEBUG_SMTP GNUNET_EXTRA_LOGGING
44 
45 #define FILTER_STRING_SIZE 64
46 
47 /* how long can a line in base64 encoded
48  mime text be? (in characters, excluding "\n") */
49 #define MAX_CHAR_PER_LINE 76
50 
51 #define EBUF_LEN 128
52 
56 typedef struct {
63 
69  char senderAddress[0];
70 } EmailAddress;
71 
73 
78 typedef struct {
80 
85 } SMTPMessage;
87 
88 /* *********** globals ************* */
89 
93 static GNUNET_CoreAPIForTransport *core_api;
94 
95 static struct GNUNET_GE_Context *ectx;
96 
100 static struct GNUNET_ThreadHandle *dispatchThread;
101 
106 
110 static char *smtp_server_name;
111 
112 static char *pipename;
113 
117 static struct GNUNET_Mutex *lock;
118 
122 static struct sigaction old_handler;
123 
124 static char *email;
125 
126 static GNUNET_TransportAPI smtpAPI;
127 
128 static GNUNET_Stats_ServiceAPI *stats;
129 
131 
132 static int stat_bytesSent;
133 
134 static int stat_bytesDropped;
135 
139 static unsigned long long rate_limit;
140 
141 static GNUNET_CronTime last_transmission;
142 
143 
144 /* ********************* the real stuff ******************* */
145 
146 #define strAUTOncmp(a, b) strncmp(a, b, strlen(b))
147 
151 static void *
152 listenAndDistribute(void *unused)
153 {
154  char *line;
155  unsigned int linesize;
156  SMTPMessage *mp;
157  FILE *fdes;
158  char *retl;
159  char *out;
160  unsigned int size;
161  GNUNET_TransportPacket *coreMP;
162  int fd;
163  unsigned int pos;
164 
165  linesize = ((GNUNET_MAX_BUFFER_SIZE * 4 / 3) + 8) * (MAX_CHAR_PER_LINE + 2) / MAX_CHAR_PER_LINE; /* maximum size of a line supported */
166  line = GNUNET_malloc(linesize + 2); /* 2 bytes for off-by-one errors, just to be safe... */
167 
168 #define READLINE(l, limit) \
169  do { retl = fgets(l, (limit), fdes); \
170  if ((retl == NULL) || (smtp_shutdown == GNUNET_YES)) { \
171  goto END; \
172  } \
173  if (core_api->load_monitor != NULL) \
174  GNUNET_network_monitor_notify_transmission (core_api->load_monitor, GNUNET_ND_DOWNLOAD, strlen(retl)); \
175  } while (0)
176 
177 
178  while (smtp_shutdown == GNUNET_NO)
179  {
180  fd = OPEN(pipename, O_RDONLY | O_ASYNC);
181  if (fd == -1)
182  {
183  if (smtp_shutdown == GNUNET_NO)
184  GNUNET_thread_sleep(5 * GNUNET_CRON_SECONDS);
185  continue;
186  }
187  fdes = fdopen(fd, "r");
188  while (smtp_shutdown == GNUNET_NO)
189  {
190  /* skip until end of header */
191  do
192  {
193  READLINE(line, linesize);
194  }
195  while ((line[0] != '\r') && (line[0] != '\n')); /* expect newline */
196  READLINE(line, linesize); /* read base64 encoded message; decode, process */
197  pos = 0;
198  while (1)
199  {
200  pos = strlen(line) - 1; /* ignore new line */
201  READLINE(&line[pos], linesize - pos); /* read base64 encoded message; decode, process */
202  if ((line[pos] == '\r') || (line[pos] == '\n'))
203  break; /* empty line => end of message! */
204  }
205  size = GNUNET_STRINGS_base64_decode(line, pos, &out);
206  if (size < sizeof(SMTPMessage))
207  {
208  GNUNET_GE_BREAK(ectx, 0);
209  GNUNET_free(out);
210  goto END;
211  }
212 
213  mp = (SMTPMessage *)&out[size - sizeof(SMTPMessage)];
214  if (ntohs(mp->header.size) != size)
215  {
216  GNUNET_GE_LOG(ectx,
217  GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
218  _("Received malformed message via %s. Ignored.\n"),
219  "SMTP");
220 #if DEBUG_SMTP
221  GNUNET_GE_LOG(ectx,
222  GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
223  "Size returned by base64=%d, in the msg=%d.\n", size,
224  ntohl(mp->size));
225 #endif
226  GNUNET_free(out);
227  goto END;
228  }
229  if (stats != NULL)
230  stats->change(stat_bytesReceived, size);
231  coreMP = GNUNET_new(GNUNET_TransportPacket);
232  coreMP->msg = out;
233  coreMP->size = size - sizeof(SMTPMessage);
234  coreMP->tsession = NULL;
235  coreMP->sender = mp->sender;
236 #if DEBUG_SMTP
237  GNUNET_GE_LOG(ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
238  "SMTP message passed to the core.\n");
239 #endif
240 
241  core_api->receive(coreMP);
242  }
243 END:
244 #if DEBUG_SMTP
245  GNUNET_GE_LOG(ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
246  "SMTP message processed.\n");
247 #endif
248  if (fdes != NULL)
249  fclose(fdes);
250  }
251  GNUNET_free(line);
252  return NULL;
253 }
254 
255 /* *************** API implementation *************** */
256 
266 static int
267 api_verify_hello(const GNUNET_MessageHello * hello)
268 {
269  const EmailAddress *maddr;
270 
271  maddr = (const EmailAddress *)&hello[1];
272  if ((ntohs(hello->header.size) !=
273  sizeof(GNUNET_MessageHello) + ntohs(hello->senderAddressSize)) ||
274  (maddr->senderAddress
275  [ntohs(hello->senderAddressSize) - 1 - FILTER_STRING_SIZE] != '\0'))
276  {
277  GNUNET_GE_BREAK(ectx, 0);
278  return GNUNET_SYSERR; /* obviously invalid */
279  }
280  if (NULL == strstr(maddr->filter, ": "))
281  return GNUNET_SYSERR;
282  return GNUNET_OK;
283 }
284 
292 static GNUNET_MessageHello *
294 {
295  GNUNET_MessageHello *msg;
296  char *filter;
297  EmailAddress *haddr;
298  int i;
299 
300  GNUNET_GC_get_configuration_value_string(core_api->cfg, "SMTP", "FILTER",
301  "X-mailer: GNUnet", &filter);
302  if (NULL == strstr(filter, ": "))
303  {
304  GNUNET_GE_LOG(ectx, GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
305  _("SMTP filter string to invalid, lacks ': '\n"));
306  GNUNET_free(filter);
307  return NULL;
308  }
309 
310  if (strlen(filter) > FILTER_STRING_SIZE)
311  {
312  filter[FILTER_STRING_SIZE] = '\0';
313  GNUNET_GE_LOG(ectx, GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
314  _("SMTP filter string to long, capped to `%s'\n"), filter);
315  }
316  i = (strlen(email) + 8) & (~7); /* make multiple of 8 */
317  msg =
318  GNUNET_malloc(sizeof(GNUNET_MessageHello) + sizeof(EmailAddress) + i);
319  memset(msg, 0, sizeof(GNUNET_MessageHello) + sizeof(EmailAddress) + i);
320  haddr = (EmailAddress *)&msg[1];
321  memset(&haddr->filter[0], 0, FILTER_STRING_SIZE);
322  strcpy(&haddr->filter[0], filter);
323  GNUNET_memcpy(&haddr->senderAddress[0], email, strlen(email) + 1);
324  msg->senderAddressSize = htons(strlen(email) + 1 + sizeof(EmailAddress));
325  msg->protocol = htons(GNUNET_TRANSPORT_PROTOCOL_NUMBER_SMTP);
326  msg->MTU = htonl(smtpAPI.mtu);
327  msg->header.size = htons(GNUNET_sizeof_hello(msg));
328  if (api_verify_hello(msg) == GNUNET_SYSERR)
329  GNUNET_GE_ASSERT(ectx, 0);
330  GNUNET_free(filter);
331  return msg;
332 }
333 
335  unsigned int esize;
336  unsigned int pos;
337  char *ebody;
338 };
339 
340 static const char *
341 get_message(void **buf, int *len, void *cls)
342 {
343  struct GetMessageClosure *gmc = cls;
344 
345  *buf = NULL;
346  if (len == NULL)
347  {
348  gmc->pos = 0;
349  return NULL;
350  }
351  if (gmc->pos == gmc->esize)
352  return NULL; /* done */
353  *len = gmc->esize;
354  gmc->pos = gmc->esize;
355  return gmc->ebody;
356 }
357 
367 static int
368 api_send(GNUNET_TSession * tsession, const void *msg, const unsigned int size,
369  int important)
370 {
371  const GNUNET_MessageHello *hello;
372  const EmailAddress *haddr;
373  char *m;
374  char *filter;
375  char *fvalue;
376  SMTPMessage *mp;
377  struct GetMessageClosure gm_cls;
378  smtp_session_t session;
379  smtp_message_t message;
380  smtp_recipient_t recipient;
381 
382 #define EBUF_LEN 128
383  char ebuf[EBUF_LEN];
384  GNUNET_CronTime now;
385 
386  if (smtp_shutdown == GNUNET_YES)
387  return GNUNET_SYSERR;
388  if ((size == 0) || (size > smtpAPI.mtu))
389  {
390  GNUNET_GE_BREAK(ectx, 0);
391  return GNUNET_SYSERR;
392  }
393  now = GNUNET_get_time();
394  if ((important != GNUNET_YES) &&
395  ((now - last_transmission) * rate_limit) < GNUNET_CRON_HOURS)
396  return GNUNET_NO; /* rate too high */
397  last_transmission = now;
398 
399  hello = (const GNUNET_MessageHello *)tsession->internal;
400  if (hello == NULL)
401  return GNUNET_SYSERR;
402  GNUNET_mutex_lock(lock);
403  session = smtp_create_session();
404  if (session == NULL)
405  {
406  GNUNET_GE_LOG(ectx,
407  GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER |
408  GNUNET_GE_IMMEDIATE, _("SMTP: `%s' failed: %s.\n"),
409  "smtp_create_session", smtp_strerror(smtp_errno(), ebuf,
410  EBUF_LEN));
411  GNUNET_mutex_unlock(lock);
412  return GNUNET_SYSERR;
413  }
414  if (0 == smtp_set_server(session, smtp_server_name))
415  {
416  GNUNET_GE_LOG(ectx,
417  GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER |
418  GNUNET_GE_IMMEDIATE, _("SMTP: `%s' failed: %s.\n"),
419  "smtp_set_server", smtp_strerror(smtp_errno(), ebuf,
420  EBUF_LEN));
421  smtp_destroy_session(session);
422  GNUNET_mutex_unlock(lock);
423  return GNUNET_SYSERR;
424  }
425  haddr = (const EmailAddress *)&hello[1];
426  message = smtp_add_message(session);
427  if (message == NULL)
428  {
429  GNUNET_GE_LOG(ectx,
430  GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_USER |
431  GNUNET_GE_BULK, _("SMTP: `%s' failed: %s.\n"),
432  "smtp_add_message", smtp_strerror(smtp_errno(), ebuf,
433  EBUF_LEN));
434  smtp_destroy_session(session);
435  GNUNET_mutex_unlock(lock);
436  return GNUNET_SYSERR;
437  }
438  smtp_set_header(message, "To", NULL, haddr->senderAddress);
439  smtp_set_header(message, "From", NULL, email);
440 
441  filter = GNUNET_strdup(haddr->filter);
442  fvalue = strstr(filter, ": ");
443  GNUNET_GE_ASSERT(NULL, NULL != fvalue);
444  fvalue[0] = '\0';
445  fvalue += 2;
446  if (0 == smtp_set_header(message, filter, fvalue))
447  {
448  GNUNET_GE_LOG(ectx,
449  GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_USER |
450  GNUNET_GE_BULK, _("SMTP: `%s' failed: %s.\n"),
451  "smtp_set_header", smtp_strerror(smtp_errno(), ebuf,
452  EBUF_LEN));
453  smtp_destroy_session(session);
454  GNUNET_mutex_unlock(lock);
455  GNUNET_free(filter);
456  return GNUNET_SYSERR;
457  }
458  GNUNET_free(filter);
459  m = GNUNET_malloc(size + sizeof(SMTPMessage));
460  GNUNET_memcpy(m, msg, size);
461  mp = (SMTPMessage *)&m[size];
462  mp->header.size = htons(size + sizeof(SMTPMessage));
463  mp->header.type = htons(0);
464  mp->sender = *core_api->my_identity;
465  gm_cls.ebody = NULL;
466  gm_cls.pos = 0;
467  gm_cls.esize = GNUNET_STRINGS_base64_encode(m, size + sizeof(SMTPMessage), &gm_cls.ebody);
468  GNUNET_free(m);
469  if (0 == smtp_size_set_estimate(message, gm_cls.esize))
470  {
471  GNUNET_GE_LOG(ectx,
472  GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_USER |
473  GNUNET_GE_BULK, _("SMTP: `%s' failed: %s.\n"),
474  "smtp_size_set_estimate", smtp_strerror(smtp_errno(), ebuf,
475  EBUF_LEN));
476  }
477  if (0 == smtp_set_messagecb(message, &get_message, &gm_cls))
478  {
479  GNUNET_GE_LOG(ectx,
480  GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_USER |
481  GNUNET_GE_BULK, _("SMTP: `%s' failed: %s.\n"),
482  "smtp_set_messagecb", smtp_strerror(smtp_errno(), ebuf,
483  EBUF_LEN));
484  smtp_destroy_session(session);
485  GNUNET_mutex_unlock(lock);
486  GNUNET_free(gm_cls.ebody);
487  return GNUNET_SYSERR;
488  }
489  recipient = smtp_add_recipient(message, haddr->senderAddress);
490  if (recipient == NULL)
491  {
492  GNUNET_GE_LOG(ectx,
493  GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_USER |
494  GNUNET_GE_BULK, _("SMTP: `%s' failed: %s.\n"),
495  "smtp_add_recipient", smtp_strerror(smtp_errno(), ebuf,
496  EBUF_LEN));
497  smtp_destroy_session(session);
498  GNUNET_mutex_unlock(lock);
499  return GNUNET_SYSERR;
500  }
501  if (0 == smtp_start_session(session))
502  {
503  GNUNET_GE_LOG(ectx,
504  GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_USER |
505  GNUNET_GE_BULK, _("SMTP: `%s' failed: %s.\n"),
506  "smtp_start_session", smtp_strerror(smtp_errno(), ebuf,
507  EBUF_LEN));
508  smtp_destroy_session(session);
509  GNUNET_mutex_unlock(lock);
510  GNUNET_free(gm_cls.ebody);
511  return GNUNET_SYSERR;
512  }
513  if (stats != NULL)
514  stats->change(stat_bytesSent, size);
515  if (core_api->load_monitor != NULL)
516  GNUNET_network_monitor_notify_transmission(core_api->load_monitor,
517  GNUNET_ND_UPLOAD, gm_cls.esize);
518  smtp_message_reset_status(message); /* this is needed to plug a 28-byte/message memory leak in libesmtp */
519  smtp_destroy_session(session);
520  GNUNET_mutex_unlock(lock);
521  GNUNET_free(gm_cls.ebody);
522  return GNUNET_OK;
523 }
524 
532 static int
533 api_connect(const GNUNET_MessageHello * hello, GNUNET_TSession ** tsessionPtr,
534  int may_reuse)
535 {
536  GNUNET_TSession *tsession;
537 
538  tsession = GNUNET_new(GNUNET_TSession);
539  tsession->internal = GNUNET_malloc(GNUNET_sizeof_hello(hello));
540  tsession->peer = hello->senderIdentity;
541  GNUNET_memcpy(tsession->internal, hello, GNUNET_sizeof_hello(hello));
542  tsession->ttype = smtpAPI.protocol_number;
543  (*tsessionPtr) = tsession;
544  return GNUNET_OK;
545 }
546 
553 static int
554 api_disconnect(GNUNET_TSession * tsession)
555 {
556  if (tsession != NULL)
557  {
558  if (tsession->internal != NULL)
559  GNUNET_free(tsession->internal);
560  GNUNET_free(tsession);
561  }
562  return GNUNET_OK;
563 }
564 
569 static int
571 {
573  /* initialize SMTP network */
574  dispatchThread = GNUNET_thread_create(&listenAndDistribute, NULL, 1024 * 4);
575  if (dispatchThread == NULL)
576  {
577  GNUNET_GE_DIE_STRERROR(ectx,
578  GNUNET_GE_ADMIN | GNUNET_GE_BULK | GNUNET_GE_FATAL,
579  "pthread_create");
580  return GNUNET_SYSERR;
581  }
582  return GNUNET_OK;
583 }
584 
589 static int
591 {
592  void *unused;
593 
595  GNUNET_thread_stop_sleep(dispatchThread);
596  GNUNET_thread_join(dispatchThread, &unused);
597  return GNUNET_OK;
598 }
599 
603 static int
604 api_hello_to_address(const GNUNET_MessageHello * hello, void **sa,
605  unsigned int *sa_len)
606 {
607  return GNUNET_SYSERR;
608 }
609 
613 static int
614 api_associate(GNUNET_TSession * tsession)
615 {
616  return GNUNET_SYSERR; /* SMTP connections can never be associated */
617 }
618 
623 static int
624 api_test_would_try(GNUNET_TSession * tsession, unsigned int size,
625  int important)
626 {
627  return GNUNET_OK; /* we always try... */
628 }
629 
634 GNUNET_TransportAPI *
635 inittransport_smtp(struct GNUNET_CoreAPIForTransport * core)
636 {
637  unsigned long long mtu;
638  struct sigaction sa;
639 
640  core_api = core;
641  ectx = core->ectx;
642  if (!GNUNET_GC_have_configuration_value(core_api->cfg, "SMTP", "EMAIL"))
643  {
644  GNUNET_GE_LOG(ectx, GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
645  _
646  ("No email-address specified, can not start SMTP transport.\n"));
647  return NULL;
648  }
649  GNUNET_GC_get_configuration_value_number(core_api->cfg, "SMTP", "MTU", 1200,
651  SMTP_MESSAGE_SIZE, &mtu);
652  GNUNET_GC_get_configuration_value_number(core_api->cfg, "SMTP", "RATELIMIT",
653  0, 0, 1024 * 1024, &rate_limit);
654  stats = core_api->service_request("stats");
655  if (stats != NULL)
656  {
658  stats->create(gettext_noop("# bytes received via SMTP"));
659  stat_bytesSent = stats->create(gettext_noop("# bytes sent via SMTP"));
661  stats->create(gettext_noop("# bytes dropped by SMTP (outgoing)"));
662  }
663  GNUNET_GC_get_configuration_value_filename(core_api->cfg, "SMTP", "PIPE", &pipename);
664  unlink(pipename);
665  if (0 != mkfifo(pipename, S_IWUSR | S_IRUSR | S_IWGRP | S_IWOTH))
666  {
667  GNUNET_GE_LOG_STRERROR(ectx,
668  GNUNET_GE_ADMIN | GNUNET_GE_BULK | GNUNET_GE_FATAL,
669  "mkfifo");
671  core_api->service_release(stats);
672  stats = NULL;
673  return NULL;
674  }
675  /* we need to allow the mailer program to send us messages;
676  * easiest done by giving it write permissions (see Mantis #1142) */
677  if (0 != chmod(pipename, S_IWUSR | S_IRUSR | S_IWGRP | S_IWOTH))
678  GNUNET_GE_LOG_STRERROR(ectx,
679  GNUNET_GE_ADMIN | GNUNET_GE_BULK |
680  GNUNET_GE_WARNING, "chmod");
681  GNUNET_GC_get_configuration_value_string(core_api->cfg, "SMTP", "EMAIL", NULL,
682  &email);
683  lock = GNUNET_mutex_create(GNUNET_NO);
684  GNUNET_GC_get_configuration_value_string(core_api->cfg, "SMTP", "SERVER",
685  "localhost:25", &smtp_server_name);
686  sa.sa_handler = SIG_IGN;
687  sigemptyset(&sa.sa_mask);
688  sa.sa_flags = 0;
689  sigaction(SIGPIPE, &sa, &old_handler);
690 
691  smtpAPI.protocol_number = GNUNET_TRANSPORT_PROTOCOL_NUMBER_SMTP;
692  smtpAPI.mtu = mtu - sizeof(SMTPMessage);
693  smtpAPI.cost = 50;
694  smtpAPI.hello_verify = &api_verify_hello;
695  smtpAPI.hello_create = &api_create_hello;
696  smtpAPI.connect = &api_connect;
697  smtpAPI.send = &api_send;
698  smtpAPI.associate = &api_associate;
699  smtpAPI.disconnect = &api_disconnect;
700  smtpAPI.server_start = &api_start_transport_server;
701  smtpAPI.server_stop = &api_stop_transport_server;
702  smtpAPI.hello_to_address = &api_hello_to_address;
703  smtpAPI.send_now_test = &api_test_would_try;
704  return &smtpAPI;
705 }
706 
707 void
709 {
710  sigaction(SIGPIPE, &old_handler, NULL);
712  if (stats != NULL)
713  {
714  core_api->service_release(stats);
715  stats = NULL;
716  }
717  GNUNET_mutex_destroy(lock);
718  lock = NULL;
719  unlink(pipename);
721  pipename = NULL;
723  email = NULL;
724 }
725 
726 /* end of smtp.c */
static void * listenAndDistribute(void *unused)
Listen to the pipe, decode messages and send to core.
static unsigned long long rate_limit
How many e-mails are we allowed to send per hour?
static char * pipename
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
char filter[64]
Filter line that every sender must include in the E-mails such that the receiver can effectively filt...
char senderAddress[0]
Claimed E-mail address of the sender.
static GNUNET_Stats_ServiceAPI * stats
static GNUNET_CronTime last_transmission
static char * smtp_server_name
Set to the SMTP server hostname (and port) for outgoing messages.
static int api_test_would_try(GNUNET_TSession *tsession, unsigned int size, int important)
Always succeeds (for now; we should look at adding frequency limits to SMTP in the future!)...
static int api_stop_transport_server()
Shutdown the server process (stop receiving inbound traffic).
Host-Address in a SMTP network.
static int stat_bytesDropped
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
We&#39;re done processing.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_new(type)
Allocate a struct or union of the given type.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
static int api_disconnect(GNUNET_TSession *tsession)
Disconnect from a remote node.
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
static GNUNET_NETWORK_STRUCT_END GNUNET_CoreAPIForTransport * core_api
apis (our advertised API and the core api )
static int api_associate(GNUNET_TSession *tsession)
Always fails.
static GNUNET_TransportAPI smtpAPI
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:99
static char * email
static struct sigaction old_handler
Old handler for SIGPIPE (kept to be able to restore).
#define READLINE(l, limit)
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
static char * line
Desired phone line (string to be converted to a hash).
void donetransport_smtp()
static char buf[2048]
static struct GNUNET_GE_Context * ectx
static struct GNUNET_CONTAINER_BloomFilter * filter
Bloomfilter to quickly tell if we don&#39;t have the content.
static int api_start_transport_server()
Start the server process to receive inbound traffic.
static int api_hello_to_address(const GNUNET_MessageHello *hello, void **sa, unsigned int *sa_len)
Convert SMTP hello to an IP address (always fails).
size_t GNUNET_STRINGS_base64_decode(const char *data, size_t len, void **output)
Decode from Base64.
Definition: strings.c:1920
size_t GNUNET_STRINGS_base64_encode(const void *in, size_t len, char **output)
Encode into Base64.
Definition: strings.c:1856
static int api_send(GNUNET_TSession *tsession, const void *msg, const unsigned int size, int important)
Send a message to the specified remote node.
#define EBUF_LEN
#define SMTP_MESSAGE_SIZE
The default maximum size of each outbound SMTP message.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static const char * get_message(void **buf, int *len, void *cls)
static unsigned int size
Size of the "table".
Definition: peer.c:66
static int api_connect(const GNUNET_MessageHello *hello, GNUNET_TSession **tsessionPtr, int may_reuse)
Establish a connection to a remote node.
static struct GNUNET_Mutex * lock
Lock for uses of libesmtp (not thread-safe).
#define FILTER_STRING_SIZE
static int smtp_shutdown
Flag to indicate that server has been shut down.
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32;.
The identity of the host (wraps the signing key of the peer).
static int api_verify_hello(const GNUNET_MessageHello *hello)
Verify that a hello-Message is correct (a node is reachable at that address).
GNUNET_MessageHeader header
Header for all communications.
static struct GNUNET_ThreadHandle * dispatchThread
Thread that listens for inbound messages.
#define GNUNET_YES
Definition: gnunet_common.h:77
GNUNET_PeerIdentity sender
What is the identity of the sender (GNUNET_hash of public key)
GNUNET_TransportAPI * inittransport_smtp(struct GNUNET_CoreAPIForTransport *core)
The exported method.
Encapsulation of a GNUnet message in the SMTP mail body (before base64 encoding). ...
static int stat_bytesReceived
#define MAX_CHAR_PER_LINE
static GNUNET_MessageHello * api_create_hello()
Create a hello-Message for the current node.
static int stat_bytesSent
#define GNUNET_malloc(size)
Wrapper around malloc.
static struct GNUNET_CORE_Handle * core
Handle to the CORE service.
#define GNUNET_free(ptr)
Wrapper around free.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
#define gettext_noop(String)
Definition: gettext.h:69