GNUnet  0.20.0
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
57 {
64 
70  char senderAddress[0];
71 } EmailAddress;
72 
74 
79 typedef struct
80 {
82 
87 } SMTPMessage;
89 
90 /* *********** globals ************* */
91 
95 static GNUNET_CoreAPIForTransport *core_api;
96 
97 static struct GNUNET_GE_Context *ectx;
98 
102 static struct GNUNET_ThreadHandle *dispatchThread;
103 
108 
112 static char *smtp_server_name;
113 
114 static char *pipename;
115 
119 static struct GNUNET_Mutex *lock;
120 
124 static struct sigaction old_handler;
125 
126 static char *email;
127 
128 static GNUNET_TransportAPI smtpAPI;
129 
130 static GNUNET_Stats_ServiceAPI *stats;
131 
133 
134 static int stat_bytesSent;
135 
136 static int stat_bytesDropped;
137 
141 static unsigned long long rate_limit;
142 
143 static GNUNET_CronTime last_transmission;
144 
145 
146 /* ********************* the real stuff ******************* */
147 
148 #define strAUTOncmp(a, b) strncmp (a, b, strlen (b))
149 
153 static void *
154 listenAndDistribute (void *unused)
155 {
156  char *line;
157  unsigned int linesize;
158  SMTPMessage *mp;
159  FILE *fdes;
160  char *retl;
161  char *out;
162  unsigned int size;
163  GNUNET_TransportPacket *coreMP;
164  int fd;
165  unsigned int pos;
166 
167  linesize = ((GNUNET_MAX_BUFFER_SIZE * 4 / 3) + 8) * (MAX_CHAR_PER_LINE + 2)
168  / MAX_CHAR_PER_LINE; /* maximum size of a line supported */
169  line = GNUNET_malloc (linesize + 2); /* 2 bytes for off-by-one errors, just to be safe... */
170 
171 #define READLINE(l, limit) \
172  do { retl = fgets (l, (limit), fdes); \
173  if ((retl == NULL) || (smtp_shutdown == GNUNET_YES)) { \
174  goto END; \
175  } \
176  if (core_api->load_monitor != NULL) \
177  GNUNET_network_monitor_notify_transmission (core_api->load_monitor, \
178  GNUNET_ND_DOWNLOAD, \
179  strlen (retl)); \
180  } while (0)
181 
182 
183  while (smtp_shutdown == GNUNET_NO)
184  {
185  fd = OPEN (pipename, O_RDONLY | O_ASYNC);
186  if (fd == -1)
187  {
188  if (smtp_shutdown == GNUNET_NO)
189  GNUNET_thread_sleep (5 * GNUNET_CRON_SECONDS);
190  continue;
191  }
192  fdes = fdopen (fd, "r");
193  while (smtp_shutdown == GNUNET_NO)
194  {
195  /* skip until end of header */
196  do
197  {
198  READLINE (line, linesize);
199  }
200  while ((line[0] != '\r') && (line[0] != '\n')); /* expect newline */
201  READLINE (line, linesize); /* read base64 encoded message; decode, process */
202  pos = 0;
203  while (1)
204  {
205  pos = strlen (line) - 1; /* ignore new line */
206  READLINE (&line[pos], linesize - pos); /* read base64 encoded message; decode, process */
207  if ((line[pos] == '\r') || (line[pos] == '\n'))
208  break; /* empty line => end of message! */
209  }
210  size = GNUNET_STRINGS_base64_decode (line, pos, &out);
211  if (size < sizeof(SMTPMessage))
212  {
213  GNUNET_GE_BREAK (ectx, 0);
214  GNUNET_free (out);
215  goto END;
216  }
217 
218  mp = (SMTPMessage *) &out[size - sizeof(SMTPMessage)];
219  if (ntohs (mp->header.size) != size)
220  {
221  GNUNET_GE_LOG (ectx,
222  GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
223  _ ("Received malformed message via %s. Ignored.\n"),
224  "SMTP");
225 #if DEBUG_SMTP
226  GNUNET_GE_LOG (ectx,
227  GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
228  "Size returned by base64=%d, in the msg=%d.\n", size,
229  ntohl (mp->size));
230 #endif
231  GNUNET_free (out);
232  goto END;
233  }
234  if (stats != NULL)
235  stats->change (stat_bytesReceived, size);
236  coreMP = GNUNET_new (GNUNET_TransportPacket);
237  coreMP->msg = out;
238  coreMP->size = size - sizeof(SMTPMessage);
239  coreMP->tsession = NULL;
240  coreMP->sender = mp->sender;
241 #if DEBUG_SMTP
242  GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
243  "SMTP message passed to the core.\n");
244 #endif
245 
246  core_api->receive (coreMP);
247  }
248 END:
249 #if DEBUG_SMTP
250  GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
251  "SMTP message processed.\n");
252 #endif
253  if (fdes != NULL)
254  fclose (fdes);
255  }
256  GNUNET_free (line);
257  return NULL;
258 }
259 
260 
261 /* *************** API implementation *************** */
262 
272 static int
273 api_verify_hello (const GNUNET_MessageHello *hello)
274 {
275  const EmailAddress *maddr;
276 
277  maddr = (const EmailAddress *) &hello[1];
278  if ((ntohs (hello->header.size) !=
279  sizeof(GNUNET_MessageHello) + ntohs (hello->senderAddressSize)) ||
280  (maddr->senderAddress
281  [ntohs (hello->senderAddressSize) - 1 - FILTER_STRING_SIZE] != '\0'))
282  {
283  GNUNET_GE_BREAK (ectx, 0);
284  return GNUNET_SYSERR; /* obviously invalid */
285  }
286  if (NULL == strstr (maddr->filter, ": "))
287  return GNUNET_SYSERR;
288  return GNUNET_OK;
289 }
290 
291 
299 static GNUNET_MessageHello *
301 {
302  GNUNET_MessageHello *msg;
303  char *filter;
304  EmailAddress *haddr;
305  int i;
306 
307  GNUNET_GC_get_configuration_value_string (core_api->cfg, "SMTP", "FILTER",
308  "X-mailer: GNUnet", &filter);
309  if (NULL == strstr (filter, ": "))
310  {
311  GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
312  _ ("SMTP filter string to invalid, lacks ': '\n"));
314  return NULL;
315  }
316 
317  if (strlen (filter) > FILTER_STRING_SIZE)
318  {
319  filter[FILTER_STRING_SIZE] = '\0';
320  GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
321  _ ("SMTP filter string to long, capped to `%s'\n"), filter);
322  }
323  i = (strlen (email) + 8) & (~7); /* make multiple of 8 */
324  msg =
325  GNUNET_malloc (sizeof(GNUNET_MessageHello) + sizeof(EmailAddress) + i);
326  memset (msg, 0, sizeof(GNUNET_MessageHello) + sizeof(EmailAddress) + i);
327  haddr = (EmailAddress *) &msg[1];
328  memset (&haddr->filter[0], 0, FILTER_STRING_SIZE);
329  strcpy (&haddr->filter[0], filter);
330  GNUNET_memcpy (&haddr->senderAddress[0], email, strlen (email) + 1);
331  msg->senderAddressSize = htons (strlen (email) + 1 + sizeof(EmailAddress));
332  msg->protocol = htons (GNUNET_TRANSPORT_PROTOCOL_NUMBER_SMTP);
333  msg->MTU = htonl (smtpAPI.mtu);
334  msg->header.size = htons (GNUNET_sizeof_hello (msg));
336  GNUNET_GE_ASSERT (ectx, 0);
338  return msg;
339 }
340 
341 
343 {
344  unsigned int esize;
345  unsigned int pos;
346  char *ebody;
347 };
348 
349 static const char *
350 get_message (void **buf, int *len, void *cls)
351 {
352  struct GetMessageClosure *gmc = cls;
353 
354  *buf = NULL;
355  if (len == NULL)
356  {
357  gmc->pos = 0;
358  return NULL;
359  }
360  if (gmc->pos == gmc->esize)
361  return NULL; /* done */
362  *len = gmc->esize;
363  gmc->pos = gmc->esize;
364  return gmc->ebody;
365 }
366 
367 
377 static int
378 api_send (GNUNET_TSession *tsession, const void *msg, const unsigned int size,
379  int important)
380 {
381  const GNUNET_MessageHello *hello;
382  const EmailAddress *haddr;
383  char *m;
384  char *filter;
385  char *fvalue;
386  SMTPMessage *mp;
387  struct GetMessageClosure gm_cls;
388  smtp_session_t session;
389  smtp_message_t message;
390  smtp_recipient_t recipient;
391 
392 #define EBUF_LEN 128
393  char ebuf[EBUF_LEN];
394  GNUNET_CronTime now;
395 
396  if (smtp_shutdown == GNUNET_YES)
397  return GNUNET_SYSERR;
398  if ((size == 0) || (size > smtpAPI.mtu))
399  {
400  GNUNET_GE_BREAK (ectx, 0);
401  return GNUNET_SYSERR;
402  }
403  now = GNUNET_get_time ();
404  if ((important != GNUNET_YES) &&
405  ( ((now - last_transmission) * rate_limit) < GNUNET_CRON_HOURS) )
406  return GNUNET_NO; /* rate too high */
407  last_transmission = now;
408 
409  hello = (const GNUNET_MessageHello *) tsession->internal;
410  if (hello == NULL)
411  return GNUNET_SYSERR;
412  GNUNET_mutex_lock (lock);
413  session = smtp_create_session ();
414  if (session == NULL)
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_create_session", smtp_strerror (smtp_errno (), ebuf,
420  EBUF_LEN));
421  GNUNET_mutex_unlock (lock);
422  return GNUNET_SYSERR;
423  }
424  if (0 == smtp_set_server (session, smtp_server_name))
425  {
426  GNUNET_GE_LOG (ectx,
427  GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER
428  | GNUNET_GE_IMMEDIATE, _ ("SMTP: `%s' failed: %s.\n"),
429  "smtp_set_server", smtp_strerror (smtp_errno (), ebuf,
430  EBUF_LEN));
431  smtp_destroy_session (session);
432  GNUNET_mutex_unlock (lock);
433  return GNUNET_SYSERR;
434  }
435  haddr = (const EmailAddress *) &hello[1];
436  message = smtp_add_message (session);
437  if (message == NULL)
438  {
439  GNUNET_GE_LOG (ectx,
440  GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_USER
441  | GNUNET_GE_BULK, _ ("SMTP: `%s' failed: %s.\n"),
442  "smtp_add_message", smtp_strerror (smtp_errno (), ebuf,
443  EBUF_LEN));
444  smtp_destroy_session (session);
445  GNUNET_mutex_unlock (lock);
446  return GNUNET_SYSERR;
447  }
448  smtp_set_header (message, "To", NULL, haddr->senderAddress);
449  smtp_set_header (message, "From", NULL, email);
450 
451  filter = GNUNET_strdup (haddr->filter);
452  fvalue = strstr (filter, ": ");
453  GNUNET_GE_ASSERT (NULL, NULL != fvalue);
454  fvalue[0] = '\0';
455  fvalue += 2;
456  if (0 == smtp_set_header (message, filter, fvalue))
457  {
458  GNUNET_GE_LOG (ectx,
459  GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_USER
460  | GNUNET_GE_BULK, _ ("SMTP: `%s' failed: %s.\n"),
461  "smtp_set_header", smtp_strerror (smtp_errno (), ebuf,
462  EBUF_LEN));
463  smtp_destroy_session (session);
464  GNUNET_mutex_unlock (lock);
466  return GNUNET_SYSERR;
467  }
469  m = GNUNET_malloc (size + sizeof(SMTPMessage));
470  GNUNET_memcpy (m, msg, size);
471  mp = (SMTPMessage *) &m[size];
472  mp->header.size = htons (size + sizeof(SMTPMessage));
473  mp->header.type = htons (0);
474  mp->sender = *core_api->my_identity;
475  gm_cls.ebody = NULL;
476  gm_cls.pos = 0;
477  gm_cls.esize = GNUNET_STRINGS_base64_encode (m, size + sizeof(SMTPMessage),
478  &gm_cls.ebody);
479  GNUNET_free (m);
480  if (0 == smtp_size_set_estimate (message, gm_cls.esize))
481  {
482  GNUNET_GE_LOG (ectx,
483  GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_USER
484  | GNUNET_GE_BULK, _ ("SMTP: `%s' failed: %s.\n"),
485  "smtp_size_set_estimate", smtp_strerror (smtp_errno (), ebuf,
486  EBUF_LEN));
487  }
488  if (0 == smtp_set_messagecb (message, &get_message, &gm_cls))
489  {
490  GNUNET_GE_LOG (ectx,
491  GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_USER
492  | GNUNET_GE_BULK, _ ("SMTP: `%s' failed: %s.\n"),
493  "smtp_set_messagecb", smtp_strerror (smtp_errno (), ebuf,
494  EBUF_LEN));
495  smtp_destroy_session (session);
496  GNUNET_mutex_unlock (lock);
497  GNUNET_free (gm_cls.ebody);
498  return GNUNET_SYSERR;
499  }
500  recipient = smtp_add_recipient (message, haddr->senderAddress);
501  if (recipient == NULL)
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_add_recipient", smtp_strerror (smtp_errno (), ebuf,
507  EBUF_LEN));
508  smtp_destroy_session (session);
509  GNUNET_mutex_unlock (lock);
510  return GNUNET_SYSERR;
511  }
512  if (0 == smtp_start_session (session))
513  {
514  GNUNET_GE_LOG (ectx,
515  GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_USER
516  | GNUNET_GE_BULK, _ ("SMTP: `%s' failed: %s.\n"),
517  "smtp_start_session", smtp_strerror (smtp_errno (), ebuf,
518  EBUF_LEN));
519  smtp_destroy_session (session);
520  GNUNET_mutex_unlock (lock);
521  GNUNET_free (gm_cls.ebody);
522  return GNUNET_SYSERR;
523  }
524  if (stats != NULL)
525  stats->change (stat_bytesSent, size);
526  if (core_api->load_monitor != NULL)
527  GNUNET_network_monitor_notify_transmission (core_api->load_monitor,
528  GNUNET_ND_UPLOAD, gm_cls.esize);
529  smtp_message_reset_status (message); /* this is needed to plug a 28-byte/message memory leak in libesmtp */
530  smtp_destroy_session (session);
531  GNUNET_mutex_unlock (lock);
532  GNUNET_free (gm_cls.ebody);
533  return GNUNET_OK;
534 }
535 
536 
544 static int
545 api_connect (const GNUNET_MessageHello *hello, GNUNET_TSession **tsessionPtr,
546  int may_reuse)
547 {
548  GNUNET_TSession *tsession;
549 
550  tsession = GNUNET_new (GNUNET_TSession);
551  tsession->internal = GNUNET_malloc (GNUNET_sizeof_hello (hello));
552  tsession->peer = hello->senderIdentity;
553  GNUNET_memcpy (tsession->internal, hello, GNUNET_sizeof_hello (hello));
554  tsession->ttype = smtpAPI.protocol_number;
555  (*tsessionPtr) = tsession;
556  return GNUNET_OK;
557 }
558 
559 
566 static int
567 api_disconnect (GNUNET_TSession *tsession)
568 {
569  if (tsession != NULL)
570  {
571  if (tsession->internal != NULL)
572  GNUNET_free (tsession->internal);
573  GNUNET_free (tsession);
574  }
575  return GNUNET_OK;
576 }
577 
578 
583 static int
585 {
587  /* initialize SMTP network */
588  dispatchThread = GNUNET_thread_create (&listenAndDistribute, NULL, 1024 * 4);
589  if (dispatchThread == NULL)
590  {
591  GNUNET_GE_DIE_STRERROR (ectx,
592  GNUNET_GE_ADMIN | GNUNET_GE_BULK | GNUNET_GE_FATAL,
593  "pthread_create");
594  return GNUNET_SYSERR;
595  }
596  return GNUNET_OK;
597 }
598 
599 
604 static int
606 {
607  void *unused;
608 
610  GNUNET_thread_stop_sleep (dispatchThread);
611  GNUNET_thread_join (dispatchThread, &unused);
612  return GNUNET_OK;
613 }
614 
615 
619 static int
620 api_hello_to_address (const GNUNET_MessageHello *hello, void **sa,
621  unsigned int *sa_len)
622 {
623  return GNUNET_SYSERR;
624 }
625 
626 
630 static int
631 api_associate (GNUNET_TSession *tsession)
632 {
633  return GNUNET_SYSERR; /* SMTP connections can never be associated */
634 }
635 
636 
641 static int
642 api_test_would_try (GNUNET_TSession *tsession, unsigned int size,
643  int important)
644 {
645  return GNUNET_OK; /* we always try... */
646 }
647 
648 
653 GNUNET_TransportAPI *
654 inittransport_smtp (struct GNUNET_CoreAPIForTransport *core)
655 {
656  unsigned long long mtu;
657  struct sigaction sa;
658 
659  core_api = core;
660  ectx = core->ectx;
661  if (! GNUNET_GC_have_configuration_value (core_api->cfg, "SMTP", "EMAIL"))
662  {
663  GNUNET_GE_LOG (ectx, GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
664  _
665  (
666  "No email-address specified, can not start SMTP transport.\n"));
667  return NULL;
668  }
669  GNUNET_GC_get_configuration_value_number (core_api->cfg, "SMTP", "MTU", 1200,
671  SMTP_MESSAGE_SIZE, &mtu);
672  GNUNET_GC_get_configuration_value_number (core_api->cfg, "SMTP", "RATELIMIT",
673  0, 0, 1024 * 1024, &rate_limit);
674  stats = core_api->service_request ("stats");
675  if (stats != NULL)
676  {
678  stats->create (gettext_noop ("# bytes received via SMTP"));
679  stat_bytesSent = stats->create (gettext_noop ("# bytes sent via SMTP"));
681  stats->create (gettext_noop ("# bytes dropped by SMTP (outgoing)"));
682  }
683  GNUNET_GC_get_configuration_value_filename (core_api->cfg, "SMTP", "PIPE",
684  &pipename);
685  unlink (pipename);
686  if (0 != mkfifo (pipename, S_IWUSR | S_IRUSR | S_IWGRP | S_IWOTH))
687  {
688  GNUNET_GE_LOG_STRERROR (ectx,
689  GNUNET_GE_ADMIN | GNUNET_GE_BULK | GNUNET_GE_FATAL,
690  "mkfifo");
692  core_api->service_release (stats);
693  stats = NULL;
694  return NULL;
695  }
696  /* we need to allow the mailer program to send us messages;
697  * easiest done by giving it write permissions (see Mantis #1142) */
698  if (0 != chmod (pipename, S_IWUSR | S_IRUSR | S_IWGRP | S_IWOTH))
699  GNUNET_GE_LOG_STRERROR (ectx,
700  GNUNET_GE_ADMIN | GNUNET_GE_BULK
701  | GNUNET_GE_WARNING, "chmod");
702  GNUNET_GC_get_configuration_value_string (core_api->cfg, "SMTP", "EMAIL",
703  NULL,
704  &email);
705  lock = GNUNET_mutex_create (GNUNET_NO);
706  GNUNET_GC_get_configuration_value_string (core_api->cfg, "SMTP", "SERVER",
707  "localhost:25", &smtp_server_name);
708  sa.sa_handler = SIG_IGN;
709  sigemptyset (&sa.sa_mask);
710  sa.sa_flags = 0;
711  sigaction (SIGPIPE, &sa, &old_handler);
712 
713  smtpAPI.protocol_number = GNUNET_TRANSPORT_PROTOCOL_NUMBER_SMTP;
714  smtpAPI.mtu = mtu - sizeof(SMTPMessage);
715  smtpAPI.cost = 50;
716  smtpAPI.hello_verify = &api_verify_hello;
717  smtpAPI.hello_create = &api_create_hello;
718  smtpAPI.connect = &api_connect;
719  smtpAPI.send = &api_send;
720  smtpAPI.associate = &api_associate;
721  smtpAPI.disconnect = &api_disconnect;
722  smtpAPI.server_start = &api_start_transport_server;
723  smtpAPI.server_stop = &api_stop_transport_server;
724  smtpAPI.hello_to_address = &api_hello_to_address;
725  smtpAPI.send_now_test = &api_test_would_try;
726  return &smtpAPI;
727 }
728 
729 
730 void
732 {
733  sigaction (SIGPIPE, &old_handler, NULL);
735  if (stats != NULL)
736  {
737  core_api->service_release (stats);
738  stats = NULL;
739  }
740  GNUNET_mutex_destroy (lock);
741  lock = NULL;
742  unlink (pipename);
744  pipename = NULL;
745  GNUNET_free (email);
746  email = NULL;
747 }
748 
749 
750 /* end of smtp.c */
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
#define gettext_noop(String)
Definition: gettext.h:70
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:104
static char * line
Desired phone line (string to be converted to a hash).
@ END
We're done processing.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
static struct GNUNET_CORE_Handle * core
Handle to the CORE service.
static struct GNUNET_CONTAINER_BloomFilter * filter
Bloomfilter to quickly tell if we don't have the content.
static char buf[2048]
Constants for network protocols.
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32.
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32;.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
size_t GNUNET_STRINGS_base64_decode(const char *data, size_t len, void **output)
Decode from Base64.
Definition: strings.c:1695
size_t GNUNET_STRINGS_base64_encode(const void *in, size_t len, char **output)
Encode into Base64.
Definition: strings.c:1607
static unsigned int size
Size of the "table".
Definition: peer.c:68
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
static unsigned long long rate_limit
How many e-mails are we allowed to send per hour?
static int api_associate(GNUNET_TSession *tsession)
Always fails.
static struct sigaction old_handler
Old handler for SIGPIPE (kept to be able to restore).
static int api_disconnect(GNUNET_TSession *tsession)
Disconnect from a remote node.
static char * smtp_server_name
Set to the SMTP server hostname (and port) for outgoing messages.
static int api_connect(const GNUNET_MessageHello *hello, GNUNET_TSession **tsessionPtr, int may_reuse)
Establish a connection to a remote node.
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 stat_bytesReceived
static struct GNUNET_Mutex * lock
Lock for uses of libesmtp (not thread-safe).
static char * email
static void * listenAndDistribute(void *unused)
Listen to the pipe, decode messages and send to core.
static GNUNET_NETWORK_STRUCT_END GNUNET_CoreAPIForTransport * core_api
apis (our advertised API and the core api )
#define READLINE(l, limit)
GNUNET_TransportAPI * inittransport_smtp(struct GNUNET_CoreAPIForTransport *core)
The exported method.
static GNUNET_TransportAPI smtpAPI
static const char * get_message(void **buf, int *len, void *cls)
void donetransport_smtp()
static int smtp_shutdown
Flag to indicate that server has been shut down.
static char * pipename
static GNUNET_Stats_ServiceAPI * stats
static int api_send(GNUNET_TSession *tsession, const void *msg, const unsigned int size, int important)
Send a message to the specified remote node.
static int api_stop_transport_server()
Shutdown the server process (stop receiving inbound traffic).
#define EBUF_LEN
static int api_start_transport_server()
Start the server process to receive inbound traffic.
static GNUNET_CronTime last_transmission
#define FILTER_STRING_SIZE
static int api_verify_hello(const GNUNET_MessageHello *hello)
Verify that a hello-Message is correct (a node is reachable at that address).
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).
#define MAX_CHAR_PER_LINE
static struct GNUNET_GE_Context * ectx
static struct GNUNET_ThreadHandle * dispatchThread
Thread that listens for inbound messages.
static GNUNET_MessageHello * api_create_hello()
Create a hello-Message for the current node.
static int stat_bytesDropped
static int stat_bytesSent
#define SMTP_MESSAGE_SIZE
The default maximum size of each outbound SMTP message.
Host-Address in a SMTP network.
char senderAddress[0]
Claimed E-mail address of the sender.
char filter[64]
Filter line that every sender must include in the E-mails such that the receiver can effectively filt...
Header for all communications.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
The identity of the host (wraps the signing key of the peer).
Encapsulation of a GNUnet message in the SMTP mail body (before base64 encoding).
GNUNET_MessageHeader header
GNUNET_PeerIdentity sender
What is the identity of the sender (GNUNET_hash of public key)