2 This file is part of GNUnet
3 (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Christian Grothoff (and other contributing authors)
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
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 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
22 * @file transport/plugin_transport_http.c
23 * @brief http transport service plugin
24 * @author Matthias Wachs
27 #include "plugin_transport_http.h"
30 * After how long do we expire an address that we
31 * learned from another peer if it is not reconfirmed
34 #define LEARNED_ADDRESS_EXPIRATION GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 6)
37 * Network format for IPv4 addresses.
39 struct IPv4HttpAddress
42 * IPv4 address, in network byte order.
44 uint32_t ipv4_addr GNUNET_PACKED;
47 * Port number, in network byte order.
49 uint16_t port GNUNET_PACKED;
53 * Wrapper to manage IPv4 addresses
55 struct IPv4HttpAddressWrapper
60 struct IPv4HttpAddressWrapper *next;
63 * Linked list previous
65 struct IPv4HttpAddressWrapper *prev;
67 struct IPv4HttpAddress *addr;
71 * Network format for IPv6 addresses.
73 struct IPv6HttpAddress
78 struct in6_addr ipv6_addr GNUNET_PACKED;
81 * Port number, in network byte order.
83 uint16_t port GNUNET_PACKED;
88 * Wrapper for IPv4 addresses.
90 struct IPv6HttpAddressWrapper
95 struct IPv6HttpAddressWrapper *next;
98 * Linked list previous
100 struct IPv6HttpAddressWrapper *prev;
102 struct IPv6HttpAddress *addr;
107 * Context for address to string conversion.
109 struct PrettyPrinterContext
112 * Function to call with the result.
114 GNUNET_TRANSPORT_AddressStringCallback asc;
119 struct Plugin *plugin;
127 * Port to add after the IP address.
134 * Encapsulation of all of the state of the plugin.
141 * Append our port and forward the result.
143 * @param cls the 'struct PrettyPrinterContext*'
144 * @param hostname hostname part of the address
147 append_port (void *cls, const char *hostname)
149 struct PrettyPrinterContext *ppc = cls;
152 if (hostname == NULL)
154 ppc->asc (ppc->asc_cls, NULL);
158 GNUNET_asprintf (&ret, "%s://%s:%d", ppc->plugin->protocol, hostname,
160 ppc->asc (ppc->asc_cls, ret);
166 * Convert the transports address to a nice, human-readable
170 * @param type name of the transport that generated the address
171 * @param addr one of the addresses of the host, NULL for the last address
172 * the specific address format depends on the transport
173 * @param addrlen length of the address
174 * @param numeric should (IP) addresses be displayed in numeric form?
175 * @param timeout after how long should we give up?
176 * @param asc function to call on each string
177 * @param asc_cls closure for asc
180 http_plugin_address_pretty_printer (void *cls, const char *type,
181 const void *addr, size_t addrlen,
183 struct GNUNET_TIME_Relative timeout,
184 GNUNET_TRANSPORT_AddressStringCallback asc,
187 GNUNET_assert (cls != NULL);
188 struct PrettyPrinterContext *ppc;
191 struct sockaddr_in a4;
192 struct sockaddr_in6 a6;
193 const struct IPv4HttpAddress *t4;
194 const struct IPv6HttpAddress *t6;
197 if (addrlen == sizeof (struct IPv6HttpAddress))
200 memset (&a6, 0, sizeof (a6));
201 a6.sin6_family = AF_INET6;
202 a6.sin6_port = t6->port;
203 memcpy (&a6.sin6_addr, &t6->ipv6_addr, sizeof (struct in6_addr));
204 port = ntohs (t6->port);
208 else if (addrlen == sizeof (struct IPv4HttpAddress))
211 memset (&a4, 0, sizeof (a4));
212 a4.sin_family = AF_INET;
213 a4.sin_port = t4->port;
214 a4.sin_addr.s_addr = t4->ipv4_addr;
215 port = ntohs (t4->ipv4_addr);
221 /* invalid address */
226 ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext));
228 ppc->asc_cls = asc_cls;
231 GNUNET_RESOLVER_hostname_get (sb, sbs, !numeric, timeout, &append_port, ppc);
237 * Another peer has suggested an address for this
238 * peer and transport plugin. Check that this could be a valid
239 * address. If so, consider adding it to the list
243 * @param addr pointer to the address
244 * @param addrlen length of addr
245 * @return GNUNET_OK if this is a plausible address for this peer
249 http_plugin_address_suggested (void *cls, const void *addr, size_t addrlen)
251 struct Plugin *plugin = cls;
252 struct IPv4HttpAddress *v4;
253 struct IPv6HttpAddress *v6;
254 struct IPv4HttpAddressWrapper *w_tv4 = plugin->ipv4_addr_head;
255 struct IPv6HttpAddressWrapper *w_tv6 = plugin->ipv6_addr_head;
257 GNUNET_assert (cls != NULL);
258 if ((addrlen != sizeof (struct IPv4HttpAddress)) &&
259 (addrlen != sizeof (struct IPv6HttpAddress)))
260 return GNUNET_SYSERR;
261 if (addrlen == sizeof (struct IPv4HttpAddress))
263 v4 = (struct IPv4HttpAddress *) addr;
264 while (w_tv4 != NULL)
267 memcmp (&w_tv4->addr->ipv4_addr, &v4->ipv4_addr, sizeof (uint32_t)))
274 return GNUNET_SYSERR;
276 if (addrlen == sizeof (struct IPv6HttpAddress))
278 v6 = (struct IPv6HttpAddress *) addr;
279 while (w_tv6 != NULL)
282 memcmp (&w_tv6->addr->ipv6_addr, &v6->ipv6_addr,
283 sizeof (struct in6_addr)))
290 return GNUNET_SYSERR;
292 return GNUNET_SYSERR;
295 struct GNUNET_TIME_Relative
296 http_plugin_receive (void *cls, const struct GNUNET_PeerIdentity * peer,
297 const struct GNUNET_MessageHeader * message,
298 struct Session * session,
299 const char *sender_address,
300 uint16_t sender_address_len)
302 struct Session *s = cls;
303 struct Plugin *plugin = s->plugin;
304 struct GNUNET_TRANSPORT_ATS_Information distance[2];
305 struct GNUNET_TIME_Relative delay;
307 distance[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE);
308 distance[0].value = htonl (1);
309 distance[1].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
310 distance[1].value = htonl (0);
312 delay = plugin->env->receive (plugin->env->cls, &s->target, message, (const struct GNUNET_TRANSPORT_ATS_Information*) &distance, 2, s, s->addr, s->addrlen);
317 * Function called for a quick conversion of the binary address to
318 * a numeric address. Note that the caller must not free the
319 * address and that the next call to this function is allowed
320 * to override the address again.
323 * @param addr binary address
324 * @param addrlen length of the address
325 * @return string representing the same address
328 http_plugin_address_to_string (void *cls, const void *addr, size_t addrlen)
330 const struct IPv4HttpAddress *t4;
331 const struct IPv6HttpAddress *t6;
332 struct sockaddr_in a4;
333 struct sockaddr_in6 a6;
335 static char rbuf[INET6_ADDRSTRLEN + 13];
339 if (addrlen == sizeof (struct IPv6HttpAddress))
341 address = GNUNET_malloc (INET6_ADDRSTRLEN);
343 a6.sin6_addr = t6->ipv6_addr;
344 inet_ntop (AF_INET6, &(a6.sin6_addr), address, INET6_ADDRSTRLEN);
345 port = ntohs (t6->port);
347 else if (addrlen == sizeof (struct IPv4HttpAddress))
349 address = GNUNET_malloc (INET_ADDRSTRLEN);
351 a4.sin_addr.s_addr = t4->ipv4_addr;
352 inet_ntop (AF_INET, &(a4.sin_addr), address, INET_ADDRSTRLEN);
353 port = ntohs (t4->port);
357 /* invalid address */
361 char * protocol = "http";
363 char * protocol = "https";
366 GNUNET_assert (strlen (address) + 7 < (INET6_ADDRSTRLEN + 13));
367 if (addrlen == sizeof (struct IPv6HttpAddress))
368 res = GNUNET_snprintf (rbuf, sizeof (rbuf), "%s://[%s]:%u/", protocol, address, port);
369 else if (addrlen == sizeof (struct IPv4HttpAddress))
370 res = GNUNET_snprintf (rbuf, sizeof (rbuf), "%s://%s:%u/", protocol, address, port);
372 GNUNET_free (address);
373 GNUNET_assert (res != 0);
378 lookup_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target,
379 struct Session * session,
380 const void *addr, size_t addrlen, int force_address)
382 struct Session *s = NULL;
383 struct Session *t = NULL;
396 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
397 "Comparing session %X <-> %X\n", session, t);
400 if (0 == memcmp (target, &t->target, sizeof (struct GNUNET_PeerIdentity)))
403 if (addrlen == t->addrlen)
405 if (0 == memcmp (addr, &t->addr, addrlen))
413 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
414 "Session %X: %s: \n", t, GNUNET_a2s (t->addr, t->addrlen));
415 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
416 "Session %X: %s: \n", session, GNUNET_a2s (session->addr, session->addrlen));
419 if(t->addrlen == session->addrlen)
421 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
423 if (0 == memcmp (session->addr, t->addr, t->addrlen))
425 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
434 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
435 "Session %X: E_PEER YES : %i E_ADDR: %i force %u: \n", t, e_peer, e_addr, force_address);
438 if ((e_peer == GNUNET_YES) && (force_address == GNUNET_NO))
443 if ((e_peer == GNUNET_YES) && (force_address == GNUNET_YES) && (e_addr == GNUNET_YES))
447 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
448 "Session %X: HERE!\n", t, e_addr, s);
452 if ((e_peer == GNUNET_YES) && (force_address == GNUNET_SYSERR))
467 delete_session (struct Session *s)
469 GNUNET_free (s->addr);
470 GNUNET_free_non_null(s->server_recv);
471 GNUNET_free_non_null(s->server_send);
476 create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target,
477 const void *addr, size_t addrlen,
478 GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
480 struct Session *s = NULL;
482 s = GNUNET_malloc (sizeof (struct Session));
483 memcpy (&s->target, target, sizeof (struct GNUNET_PeerIdentity));
485 s->addr = GNUNET_malloc (addrlen);
486 memcpy (s->addr, addr, addrlen);
487 s->addrlen = addrlen;
488 s->transmit_cont = cont;
489 s->transmit_cont_cls = cont_cls;
491 s->delay = GNUNET_TIME_absolute_get_forever();
496 notify_session_end (void *cls,
497 const struct GNUNET_PeerIdentity *
498 peer, struct Session * s)
500 struct Plugin *plugin = cls;
502 plugin->env->session_end (NULL, peer, s);
503 GNUNET_CONTAINER_DLL_remove (plugin->head, plugin->tail, s);
509 * Function that can be used by the transport service to transmit
510 * a message using the plugin. Note that in the case of a
511 * peer disconnecting, the continuation MUST be called
512 * prior to the disconnect notification itself. This function
513 * will be called with this peer's HELLO message to initiate
514 * a fresh connection to another peer.
517 * @param target who should receive this message
518 * @param msgbuf the message to transmit
519 * @param msgbuf_size number of bytes in 'msgbuf'
520 * @param priority how important is the message (most plugins will
521 * ignore message priority and just FIFO)
522 * @param to how long to wait at most for the transmission (does not
523 * require plugins to discard the message after the timeout,
524 * just advisory for the desired delay; most plugins will ignore
526 * @param session which session must be used (or NULL for "any")
527 * @param addr the address to use (can be NULL if the plugin
528 * is "on its own" (i.e. re-use existing TCP connection))
529 * @param addrlen length of the address in bytes
530 * @param force_address GNUNET_YES if the plugin MUST use the given address,
531 * GNUNET_NO means the plugin may use any other address and
532 * GNUNET_SYSERR means that only reliable existing
533 * bi-directional connections should be used (regardless
535 * @param cont continuation to call once the message has
536 * been transmitted (or if the transport is ready
537 * for the next transmission call; or if the
538 * peer disconnected...); can be NULL
539 * @param cont_cls closure for cont
540 * @return number of bytes used (on the physical network, with overheads);
541 * -1 on hard errors (i.e. address invalid); 0 is a legal value
542 * and does NOT mean that the message was not transmitted (DV)
545 http_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target,
546 const char *msgbuf, size_t msgbuf_size, unsigned int priority,
547 struct GNUNET_TIME_Relative to, struct Session *session,
548 const void *addr, size_t addrlen, int force_address,
549 GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
551 struct Plugin *plugin = cls;
552 struct HTTP_Message *msg;
553 GNUNET_assert (plugin != NULL);
555 int res = GNUNET_SYSERR;
558 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
559 "Sending %u bytes to peer `%s' on address `%s' %X %i\n", msgbuf_size,
560 GNUNET_i2s (target), GNUNET_a2s (addr, addrlen), session, force_address);
563 struct Session *s = NULL;
565 /* look for existing connection */
566 s = lookup_session (plugin, target, session, addr, addrlen, 1);
568 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
569 "%s exisiting session\n", (s!=NULL) ? "Found" : "NOT Found");
575 /* create new outbound connection */
578 if (plugin->max_connections <= plugin->cur_connections)
580 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, plugin->name,
581 "Maximum number of connections reached, "
582 "cannot connect to peer `%s'\n",
583 GNUNET_i2s (target));
588 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
589 "Initiiating new connection to peer `%s'\n",
590 GNUNET_i2s (target));
592 s = create_session (plugin, target, addr, addrlen, cont, cont_cls);
593 GNUNET_CONTAINER_DLL_insert (plugin->head, plugin->tail, s);
594 // initiate new connection
595 if (GNUNET_SYSERR == (res = client_connect (s)))
597 GNUNET_CONTAINER_DLL_remove (plugin->head, plugin->tail, s);
599 return GNUNET_SYSERR;
603 msg = GNUNET_malloc (sizeof (struct HTTP_Message) + msgbuf_size);
605 msg->size = msgbuf_size;
607 msg->buf = (char *) &msg[1];
608 msg->transmit_cont = cont;
609 msg->transmit_cont_cls = cont_cls;
610 memcpy (msg->buf, msgbuf, msgbuf_size);
612 if (s->inbound == GNUNET_NO)
615 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
616 "Using client session to send to `%s'\n",
617 GNUNET_i2s (target));
619 client_send (s, msg);
622 if (s->inbound == GNUNET_YES)
624 server_send (s, msg);
627 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
628 "Using server session to send to `%s'\n",
629 GNUNET_i2s (target));
638 * Function that can be used to force the plugin to disconnect
639 * from the given peer and cancel all previous transmissions
640 * (and their continuationc).
643 * @param target peer from which to disconnect
646 http_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target)
648 struct Plugin *plugin = cls;
649 struct Session *next = NULL;
650 struct Session *s = plugin->head;
655 if (0 == memcmp (target, &s->target, sizeof (struct GNUNET_PeerIdentity)))
657 if (s->inbound == GNUNET_NO)
658 GNUNET_assert (GNUNET_OK == client_disconnect (s));
660 GNUNET_assert (GNUNET_OK == server_disconnect (s));
661 GNUNET_CONTAINER_DLL_remove (plugin->head, plugin->tail, s);
669 * Function called by the NAT subsystem suggesting another peer wants
670 * to connect to us via connection reversal. Try to connect back to the
674 * @param addr address to try
675 * @param addrlen number of bytes in addr
678 nat_connection_reversal (void *cls, const struct sockaddr *addr,
687 nat_add_address (void *cls, int add_remove, const struct sockaddr *addr,
690 struct Plugin *plugin = cls;
691 struct IPv4HttpAddress *t4 = NULL;
692 struct IPv4HttpAddressWrapper *w_t4 = NULL;
693 struct IPv6HttpAddress *t6 = NULL;
694 struct IPv6HttpAddressWrapper *w_t6 = NULL;
697 af = addr->sa_family;
701 w_t4 = plugin->ipv4_addr_head;
704 int res = memcmp (&w_t4->addr->ipv4_addr,
705 &((struct sockaddr_in *) addr)->sin_addr,
706 sizeof (struct in_addr));
714 w_t4 = GNUNET_malloc (sizeof (struct IPv4HttpAddressWrapper));
715 t4 = GNUNET_malloc (sizeof (struct IPv4HttpAddress));
716 memcpy (&t4->ipv4_addr, &((struct sockaddr_in *) addr)->sin_addr,
717 sizeof (struct in_addr));
718 t4->port = htons (plugin->port);
722 GNUNET_CONTAINER_DLL_insert (plugin->ipv4_addr_head,
723 plugin->ipv4_addr_tail, w_t4);
725 plugin->env->notify_address (plugin->env->cls, add_remove, w_t4->addr,
726 sizeof (struct IPv4HttpAddress));
730 w_t6 = plugin->ipv6_addr_head;
733 int res = memcmp (&w_t6->addr->ipv6_addr,
734 &((struct sockaddr_in6 *) addr)->sin6_addr,
735 sizeof (struct in6_addr));
743 w_t6 = GNUNET_malloc (sizeof (struct IPv6HttpAddressWrapper));
744 t6 = GNUNET_malloc (sizeof (struct IPv6HttpAddress));
746 memcpy (&t6->ipv6_addr, &((struct sockaddr_in6 *) addr)->sin6_addr,
747 sizeof (struct in6_addr));
748 t6->port = htons (plugin->port);
752 GNUNET_CONTAINER_DLL_insert (plugin->ipv6_addr_head,
753 plugin->ipv6_addr_tail, w_t6);
755 plugin->env->notify_address (plugin->env->cls, add_remove, w_t6->addr,
756 sizeof (struct IPv6HttpAddress));
765 nat_remove_address (void *cls, int add_remove, const struct sockaddr *addr,
768 struct Plugin *plugin = cls;
769 struct IPv4HttpAddressWrapper *w_t4 = NULL;
770 struct IPv6HttpAddressWrapper *w_t6 = NULL;
773 af = addr->sa_family;
777 w_t4 = plugin->ipv4_addr_head;
780 int res = memcmp (&w_t4->addr->ipv4_addr,
781 &((struct sockaddr_in *) addr)->sin_addr,
782 sizeof (struct in_addr));
790 plugin->env->notify_address (plugin->env->cls, add_remove, w_t4->addr,
791 sizeof (struct IPv4HttpAddress));
793 GNUNET_CONTAINER_DLL_remove (plugin->ipv4_addr_head, plugin->ipv4_addr_tail,
795 GNUNET_free (w_t4->addr);
799 w_t6 = plugin->ipv6_addr_head;
802 int res = memcmp (&w_t6->addr->ipv6_addr,
803 &((struct sockaddr_in6 *) addr)->sin6_addr,
804 sizeof (struct in6_addr));
812 plugin->env->notify_address (plugin->env->cls, add_remove, w_t6->addr,
813 sizeof (struct IPv6HttpAddress));
815 GNUNET_CONTAINER_DLL_remove (plugin->ipv6_addr_head, plugin->ipv6_addr_tail,
817 GNUNET_free (w_t6->addr);
827 * Our external IP address/port mapping has changed.
829 * @param cls closure, the 'struct LocalAddrList'
830 * @param add_remove GNUNET_YES to mean the new public IP address, GNUNET_NO to mean
831 * the previous (now invalid) one
832 * @param addr either the previous or the new public IP address
833 * @param addrlen actual lenght of the address
836 nat_port_map_callback (void *cls, int add_remove, const struct sockaddr *addr,
839 GNUNET_assert (cls != NULL);
840 struct Plugin *plugin = cls;
843 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
844 "NPMC called %s to address `%s'\n",
845 (add_remove == GNUNET_NO) ? "remove" : "add",
846 GNUNET_a2s (addr, addrlen));
848 /* convert 'addr' to our internal format */
854 nat_add_address (cls, add_remove, addr, addrlen);
859 nat_remove_address (cls, add_remove, addr, addrlen);
866 start_report_addresses (struct Plugin *plugin)
869 struct sockaddr **addrs;
873 GNUNET_SERVICE_get_server_addresses (plugin->name, plugin->env->cfg,
876 if (res != GNUNET_SYSERR)
879 GNUNET_NAT_register (plugin->env->cfg, GNUNET_YES, plugin->port,
881 (const struct sockaddr **) addrs, addrlens,
882 &nat_port_map_callback, &nat_connection_reversal,
887 GNUNET_assert (addrs[res] != NULL);
888 GNUNET_free (addrs[res]);
890 GNUNET_free_non_null (addrs);
891 GNUNET_free_non_null (addrlens);
896 GNUNET_NAT_register (plugin->env->cfg, GNUNET_YES, 0, 0, NULL, NULL,
897 NULL, &nat_connection_reversal, plugin);
902 stop_report_addresses (struct Plugin *plugin)
904 /* Stop NAT handle */
905 GNUNET_NAT_unregister (plugin->nat);
907 /* Clean up addresses */
908 struct IPv4HttpAddressWrapper *w_t4;
909 struct IPv6HttpAddressWrapper *w_t6;
911 while (plugin->ipv4_addr_head != NULL)
913 w_t4 = plugin->ipv4_addr_head;
914 GNUNET_CONTAINER_DLL_remove (plugin->ipv4_addr_head, plugin->ipv4_addr_tail,
916 GNUNET_free (w_t4->addr);
920 while (plugin->ipv6_addr_head != NULL)
922 w_t6 = plugin->ipv6_addr_head;
923 GNUNET_CONTAINER_DLL_remove (plugin->ipv6_addr_head, plugin->ipv6_addr_tail,
925 GNUNET_free (w_t6->addr);
931 configure_plugin (struct Plugin *plugin)
936 if (GNUNET_CONFIGURATION_have_value
937 (plugin->env->cfg, plugin->name, "USE_IPv4"))
940 GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg, plugin->name,
944 plugin->ipv4 = GNUNET_YES;
947 if (GNUNET_CONFIGURATION_have_value
948 (plugin->env->cfg, plugin->name, "USE_IPv6"))
951 GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg, plugin->name,
955 plugin->ipv6 = GNUNET_YES;
957 if ((plugin->ipv4 == GNUNET_NO) && (plugin->ipv6 == GNUNET_NO))
959 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
961 ("Neither IPv4 nor IPv6 are enabled! Fix in configuration\n"),
965 /* Reading port number from config file */
966 unsigned long long port;
969 GNUNET_CONFIGURATION_get_value_number (plugin->env->cfg, plugin->name,
970 "PORT", &port)) || (port > 65535))
972 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
973 _("Port is required! Fix in configuration\n"),
979 /* Optional parameters */
980 unsigned long long maxneigh;
982 GNUNET_CONFIGURATION_get_value_number (plugin->env->cfg, plugin->name,
983 "MAX_CONNECTIONS", &maxneigh))
985 plugin->max_connections = maxneigh;
991 * Entry point for the plugin.
994 LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls)
996 struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
997 struct GNUNET_TRANSPORT_PluginFunctions *api;
998 struct Plugin *plugin;
1001 plugin = GNUNET_malloc (sizeof (struct Plugin));
1003 api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
1005 api->send = &http_plugin_send;
1006 api->disconnect = &http_plugin_disconnect;
1007 api->address_pretty_printer = &http_plugin_address_pretty_printer;
1008 api->check_address = &http_plugin_address_suggested;
1009 api->address_to_string = &http_plugin_address_to_string;
1012 plugin->name = "transport-https";
1013 plugin->protocol = "https";
1015 plugin->name = "transport-http";
1016 plugin->protocol = "http";
1018 /* Configure plugin from configuration */
1020 res = configure_plugin (plugin);
1021 if (res == GNUNET_SYSERR)
1023 GNUNET_free (plugin);
1029 res = client_start (plugin);
1030 if (res == GNUNET_SYSERR)
1032 GNUNET_free (plugin);
1038 res = server_start (plugin);
1039 if (res == GNUNET_SYSERR)
1041 server_stop (plugin);
1042 client_stop (plugin);
1044 GNUNET_free (plugin);
1049 /* Report addresses to transport service */
1050 start_report_addresses (plugin);
1053 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
1054 "Plugin `%s' loaded\n", plugin->name);
1062 * Exit point from the plugin.
1065 LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls)
1067 struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
1068 struct Plugin *plugin = api->cls;
1069 struct Session *s = NULL;
1071 /* Stop reporting addresses to transport service */
1072 stop_report_addresses (plugin);
1074 /* cleaning up sessions */
1078 struct Session *t = s->next;
1080 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
1081 "Disconnecting `%s' \n", GNUNET_i2s (&s->target));
1083 if (s->inbound == GNUNET_NO)
1084 GNUNET_assert (GNUNET_OK == client_disconnect (s));
1086 GNUNET_assert (GNUNET_OK == server_disconnect (s));
1088 GNUNET_CONTAINER_DLL_remove (plugin->head, plugin->tail, s);
1094 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
1095 "Stopping server\n");
1098 server_stop (plugin);
1101 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
1102 "Stopping client\n");
1105 client_stop (plugin);
1109 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
1110 "Plugin `%s' unloaded\n", plugin->name);
1113 GNUNET_free (plugin);
1119 /* end of plugin_transport_http.c */