GNUnet  0.10.x
Data Structures | Macros | Typedefs | Enumerations | Functions
plugin_transport_tcp.c File Reference

Implementation of the TCP transport service. More...

#include "platform.h"
#include "gnunet_hello_lib.h"
#include "gnunet_constants.h"
#include "gnunet_util_lib.h"
#include "gnunet_nat_service.h"
#include "gnunet_protocols.h"
#include "gnunet_resolver_service.h"
#include "gnunet_signatures.h"
#include "gnunet_statistics_service.h"
#include "gnunet_transport_service.h"
#include "gnunet_transport_plugin.h"
#include "transport.h"
#include "tcp_connection_legacy.c"
#include "tcp_server_mst_legacy.c"
#include "tcp_server_legacy.c"
#include "tcp_service_legacy.c"
Include dependency graph for plugin_transport_tcp.c:

Go to the source code of this file.

Data Structures

struct  GNUNET_CONNECTION_Credentials
 Credentials for UNIX domain sockets. More...
 
struct  GNUNET_SERVER_MessageHandler
 Message handler. More...
 
struct  WelcomeMessage
 Initial handshake message for a session. More...
 
struct  TCP_NAT_ProbeMessage
 Basically a WELCOME message, but with the purpose of giving the waiting peer a client handle to use. More...
 
struct  TCPProbeContext
 Context for sending a NAT probe via TCP. More...
 
struct  IPv4TcpAddress
 Network format for IPv4 addresses. More...
 
struct  IPv6TcpAddress
 Network format for IPv6 addresses. More...
 
struct  PendingMessage
 List containing all messages that are yet to be send. More...
 
struct  GNUNET_ATS_Session
 Information about ongoing sessions of the transport client. More...
 
struct  PrettyPrinterContext
 Closure for append_port(). More...
 
struct  Plugin
 Handle for a plugin. More...
 
struct  GNUNET_ATS_SessionItCtx
 Closure for session_lookup_it(). More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from(kind, "transport-tcp", __VA_ARGS__)
 
#define PLUGIN_NAME   "tcp"
 
#define NAT_TIMEOUT   GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 10)
 How long until we give up on establishing an NAT connection? Must be > 4 RTT. More...
 
#define GNUNET_SERVER_client_get_user_context(client, type)   (type *)GNUNET_SERVER_client_get_user_context_(client, sizeof(type))
 Return user context associated with the given client. More...
 
#define GNUNET_SERVER_client_set_user_context(client, value)   GNUNET_SERVER_client_set_user_context_(client, value, sizeof(*value))
 Set user context to be associated with the given client. More...
 

Typedefs

typedef size_t(* GNUNET_CONNECTION_TransmitReadyNotify) (void *cls, size_t size, void *buf)
 Function called to notify a client about the connection begin ready to queue more data. More...
 
typedef void(* GNUNET_SERVER_DisconnectCallback) (void *cls, struct GNUNET_SERVER_Client *client)
 Functions with this signature are called whenever a client is disconnected on the network level. More...
 
typedef void(* GNUNET_SERVER_ConnectCallback) (void *cls, struct GNUNET_SERVER_Client *client)
 Functions with this signature are called whenever a client is connected on the network level. More...
 
typedef int(* GNUNET_CONNECTION_AccessCheck) (void *cls, const struct GNUNET_CONNECTION_Credentials *ucred, const struct sockaddr *addr, socklen_t addrlen)
 Function to call for access control checks. More...
 
typedef void(* GNUNET_CONNECTION_Receiver) (void *cls, const void *buf, size_t available, const struct sockaddr *addr, socklen_t addrlen, int errCode)
 Callback function for data received from the network. More...
 
typedef void *(* GNUNET_SERVER_MstCreateCallback) (void *cls, struct GNUNET_SERVER_Client *client)
 Signature of a function to create a custom tokenizer. More...
 
typedef void(* GNUNET_SERVER_MstDestroyCallback) (void *cls, void *mst)
 Signature of a function to destroy a custom tokenizer. More...
 
typedef int(* GNUNET_SERVER_MstReceiveCallback) (void *cls, void *mst, struct GNUNET_SERVER_Client *client, const char *buf, size_t size, int purge, int one_shot)
 Signature of a function to receive data for a custom tokenizer. More...
 
typedef void(* GNUNET_SERVER_MessageCallback) (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message)
 Functions with this signature are called whenever a message is received. More...
 
typedef int(* GNUNET_SERVER_MessageTokenizerCallback) (void *cls, void *client, const struct GNUNET_MessageHeader *message)
 Functions with this signature are called whenever a complete message is received by the tokenizer. More...
 
typedef void(* LEGACY_SERVICE_Main) (void *cls, struct GNUNET_SERVER_Handle *server, const struct GNUNET_CONFIGURATION_Handle *cfg)
 Function called by the service's run method to run service-specific setup code. More...
 

Enumerations

enum  LEGACY_SERVICE_Options { LEGACY_SERVICE_OPTION_NONE = 0, LEGACY_SERVICE_OPTION_MANUAL_SHUTDOWN = 1, LEGACY_SERVICE_OPTION_SOFT_SHUTDOWN = 2 }
 Options for the service (bitmask). More...
 
enum  TcpAddressOptions { TCP_OPTIONS_NONE = 0, TCP_OPTIONS_RESERVED = 1, TCP_OPTIONS_TCP_STEALTH = 2 }
 Bits in the options field of TCP addresses. More...
 

Functions

void LEGACY_SERVICE_stop (struct LEGACY_SERVICE_Context *srv)
 Stops a service that was started with GNUNET_SERVICE_start(). More...
 
void GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection)
 Close the connection and free associated resources. More...
 
void GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client)
 Ask the server to disconnect from the given client. More...
 
void * GNUNET_SERVER_client_get_user_context_ (struct GNUNET_SERVER_Client *client, size_t size)
 Return user context associated with the given client. More...
 
struct GNUNET_SERVER_MessageStreamTokenizerGNUNET_SERVER_mst_create (GNUNET_SERVER_MessageTokenizerCallback cb, void *cb_cls)
 Create a message stream tokenizer. More...
 
int GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst, void *client_identity, const char *buf, size_t size, int purge, int one_shot)
 Add incoming data to the receive buffer and call the callback for all complete messages. More...
 
void GNUNET_SERVER_mst_destroy (struct GNUNET_SERVER_MessageStreamTokenizer *mst)
 Destroys a tokenizer. More...
 
void GNUNET_SERVER_client_set_user_context_ (struct GNUNET_SERVER_Client *client, void *ptr, size_t size)
 Set user context to be associated with the given client. More...
 
struct GNUNET_SERVER_TransmitHandleGNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client, size_t size, struct GNUNET_TIME_Relative timeout, GNUNET_CONNECTION_TransmitReadyNotify callback, void *callback_cls)
 Notify us when the server has enough space to transmit a message of the given size to the given client. More...
 
void GNUNET_SERVER_notify_transmit_ready_cancel (struct GNUNET_SERVER_TransmitHandle *th)
 Abort transmission request. More...
 
void GNUNET_SERVER_client_keep (struct GNUNET_SERVER_Client *client)
 Notify the server that the given client handle should be kept (keeps the connection up if possible, increments the internal reference counter). More...
 
void GNUNET_SERVER_client_drop (struct GNUNET_SERVER_Client *client)
 Notify the server that the given client handle is no longer required. More...
 
void GNUNET_SERVER_suspend (struct GNUNET_SERVER_Handle *server)
 Suspend accepting connections from the listen socket temporarily. More...
 
struct GNUNET_SERVER_ClientGNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server, struct GNUNET_CONNECTION_Handle *connection)
 Add a TCP socket-based connection to the set of handles managed by this server. More...
 
void GNUNET_SERVER_resume (struct GNUNET_SERVER_Handle *server)
 Resume accepting connections from the listen socket. More...
 
void GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *server)
 Free resources held by this server. More...
 
static int get_server_addresses (const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg, struct sockaddr ***addrs, socklen_t **addr_lens)
 Get the list of addresses that a server for the given service should bind to. More...
 
static void notify_session_monitor (struct Plugin *plugin, struct GNUNET_ATS_Session *session, enum GNUNET_TRANSPORT_SessionState state)
 If a session monitor is attached, notify it about the new session state. More...
 
static void tcp_nat_port_map_callback (void *cls, void **app_ctx, int add_remove, enum GNUNET_NAT_AddressClass ac, const struct sockaddr *addr, socklen_t addrlen)
 Our external IP address/port mapping has changed. More...
 
static const char * tcp_plugin_address_to_string (void *cls, const void *addr, size_t addrlen)
 Function called for a quick conversion of the binary address to a numeric address. More...
 
static int tcp_plugin_string_to_address (void *cls, const char *addr, uint16_t addrlen, void **buf, size_t *added)
 Function called to convert a string address to a binary address. More...
 
static struct GNUNET_ATS_Sessionlookup_session_by_client (struct Plugin *plugin, struct GNUNET_SERVER_Client *client)
 Find the session handle for the given client. More...
 
static int tcp_plugin_disconnect_session (void *cls, struct GNUNET_ATS_Session *session)
 Functions with this signature are called whenever we need to close a session due to a disconnect or failure to establish a connection. More...
 
static unsigned int tcp_plugin_query_keepalive_factor (void *cls)
 Function that is called to get the keepalive factor. More...
 
static void session_timeout (void *cls)
 Session was idle for too long, so disconnect it. More...
 
static void reschedule_session_timeout (struct GNUNET_ATS_Session *s)
 Increment session timeout due to activity. More...
 
static struct GNUNET_ATS_Sessioncreate_session (struct Plugin *plugin, const struct GNUNET_HELLO_Address *address, enum GNUNET_NetworkType scope, struct GNUNET_SERVER_Client *client, int is_nat)
 Create a new session. More...
 
static void process_pending_messages (struct GNUNET_ATS_Session *session)
 If we have pending messages, ask the server to transmit them (schedule the respective tasks, etc.) More...
 
static size_t do_transmit (void *cls, size_t size, void *buf)
 Function called to notify a client about the socket being ready to queue more data. More...
 
static ssize_t tcp_plugin_send (void *cls, struct GNUNET_ATS_Session *session, const char *msgbuf, size_t msgbuf_size, unsigned int priority, struct GNUNET_TIME_Relative to, GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
 Function that can be used by the transport service to transmit a message using the plugin. More...
 
static int session_lookup_it (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
 Look for a session by address. More...
 
static void nat_connect_timeout (void *cls)
 Task cleaning up a NAT connection attempt after timeout. More...
 
static void tcp_plugin_update_session_timeout (void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_ATS_Session *session)
 Function that will be called whenever the transport service wants to notify the plugin that a session is still active and in use and therefore the session timeout for this session has to be updated. More...
 
static void delayed_done (void *cls)
 Task to signal the server that we can continue receiving from the TCP client now. More...
 
static void tcp_plugin_update_inbound_delay (void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_ATS_Session *session, struct GNUNET_TIME_Relative delay)
 Function that will be called whenever the transport service wants to notify the plugin that the inbound quota changed and that the plugin should update it's delay for the next receive value. More...
 
static struct GNUNET_ATS_Sessiontcp_plugin_get_session (void *cls, const struct GNUNET_HELLO_Address *address)
 Create a new session to transmit data to the target This session will used to send data to this peer and the plugin will notify us by calling the env->session_end function. More...
 
static int session_disconnect_it (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
 We have been asked to destroy all connections to a particular peer. More...
 
static void tcp_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target)
 Function that can be called to force a disconnect from the specified neighbour. More...
 
static void append_port (void *cls, const char *hostname)
 We are processing an address pretty printing request and finished the IP resolution (if applicable). More...
 
static void tcp_plugin_address_pretty_printer (void *cls, const char *type, const void *addr, size_t addrlen, int numeric, struct GNUNET_TIME_Relative timeout, GNUNET_TRANSPORT_AddressStringCallback asc, void *asc_cls)
 Convert the transports address to a nice, human-readable format. More...
 
static int tcp_plugin_check_address (void *cls, const void *addr, size_t addrlen)
 Function that will be called to check if a binary address for this plugin is well-formed and corresponds to an address for THIS peer (as per our configuration). More...
 
static void handle_tcp_nat_probe (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message)
 We've received a nat probe from this peer via TCP. More...
 
static void handle_tcp_welcome (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message)
 We've received a welcome from this peer via TCP. More...
 
static void handle_tcp_data (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message)
 We've received data for this peer via TCP. More...
 
static void connect_notify (void *cls, struct GNUNET_SERVER_Client *client)
 Function called whenever a peer is connected on the "SERVER" level. More...
 
static void disconnect_notify (void *cls, struct GNUNET_SERVER_Client *client)
 Function called whenever a peer is disconnected on the "SERVER" level. More...
 
static size_t notify_send_probe (void *cls, size_t size, void *buf)
 We can now send a probe message, copy into buffer to really send. More...
 
static void try_connection_reversal (void *cls, const struct sockaddr *addr, socklen_t addrlen)
 Function called by the NAT subsystem suggesting another peer wants to connect to us via connection reversal. More...
 
static enum GNUNET_NetworkType tcp_plugin_get_network (void *cls, struct GNUNET_ATS_Session *session)
 Function obtain the network type for a session. More...
 
static enum GNUNET_NetworkType tcp_plugin_get_network_for_address (void *cls, const struct GNUNET_HELLO_Address *address)
 Function obtain the network type for an address. More...
 
static int send_session_info_iter (void *cls, const struct GNUNET_PeerIdentity *peer, void *value)
 Return information about the given session to the monitor callback. More...
 
static void tcp_plugin_setup_monitor (void *cls, GNUNET_TRANSPORT_SessionInfoCallback sic, void *sic_cls)
 Begin monitoring sessions of a plugin. More...
 
void * libgnunet_plugin_transport_tcp_init (void *cls)
 Entry point for the plugin. More...
 
void * libgnunet_plugin_transport_tcp_done (void *cls)
 Exit point from the plugin. More...
 

Detailed Description

Implementation of the TCP transport service.

Author
Christian Grothoff

Definition in file plugin_transport_tcp.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from(kind, "transport-tcp", __VA_ARGS__)

◆ PLUGIN_NAME

#define PLUGIN_NAME   "tcp"

◆ NAT_TIMEOUT

How long until we give up on establishing an NAT connection? Must be > 4 RTT.

Definition at line 46 of file plugin_transport_tcp.c.

Referenced by tcp_plugin_get_session().

◆ GNUNET_SERVER_client_get_user_context

#define GNUNET_SERVER_client_get_user_context (   client,
  type 
)    (type *)GNUNET_SERVER_client_get_user_context_(client, sizeof(type))

Return user context associated with the given client.

Parameters
clientclient to query
typeexpected return type (i.e. 'struct Foo')
Returns
pointer to user context of type 'type *'.

Definition at line 409 of file plugin_transport_tcp.c.

Referenced by lookup_session_by_client().

◆ GNUNET_SERVER_client_set_user_context

#define GNUNET_SERVER_client_set_user_context (   client,
  value 
)    GNUNET_SERVER_client_set_user_context_(client, value, sizeof(*value))

Set user context to be associated with the given client.

Parameters
clientclient to query
valuepointer to user context

Definition at line 418 of file plugin_transport_tcp.c.

Referenced by create_session(), handle_tcp_nat_probe(), and tcp_plugin_disconnect_session().

Typedef Documentation

◆ GNUNET_CONNECTION_TransmitReadyNotify

typedef size_t(* GNUNET_CONNECTION_TransmitReadyNotify) (void *cls, size_t size, void *buf)

Function called to notify a client about the connection begin ready to queue more data.

buf will be NULL and size zero if the connection was closed for writing in the meantime.

Parameters
clsclosure
sizenumber of bytes available in buf
bufwhere the callee should write the message
Returns
number of bytes written to buf

Definition at line 99 of file plugin_transport_tcp.c.

◆ GNUNET_SERVER_DisconnectCallback

typedef void(* GNUNET_SERVER_DisconnectCallback) (void *cls, struct GNUNET_SERVER_Client *client)

Functions with this signature are called whenever a client is disconnected on the network level.

Parameters
clsclosure
clientidentification of the client; NULL for the last call when the server is destroyed

Definition at line 127 of file plugin_transport_tcp.c.

◆ GNUNET_SERVER_ConnectCallback

typedef void(* GNUNET_SERVER_ConnectCallback) (void *cls, struct GNUNET_SERVER_Client *client)

Functions with this signature are called whenever a client is connected on the network level.

Parameters
clsclosure
clientidentification of the client

Definition at line 139 of file plugin_transport_tcp.c.

◆ GNUNET_CONNECTION_AccessCheck

typedef int(* GNUNET_CONNECTION_AccessCheck) (void *cls, const struct GNUNET_CONNECTION_Credentials *ucred, const struct sockaddr *addr, socklen_t addrlen)

Function to call for access control checks.

Parameters
clsclosure
ucredcredentials, if available, otherwise NULL
addraddress
addrlenlength of address
Returns
GNUNET_YES to allow, GNUNET_NO to deny, GNUNET_SYSERR for unknown address family (will be denied).

Definition at line 154 of file plugin_transport_tcp.c.

◆ GNUNET_CONNECTION_Receiver

typedef void(* GNUNET_CONNECTION_Receiver) (void *cls, const void *buf, size_t available, const struct sockaddr *addr, socklen_t addrlen, int errCode)

Callback function for data received from the network.

Note that both "available" and "err" would be 0 if the read simply timed out.

Parameters
clsclosure
bufpointer to received data
availablenumber of bytes availabe in "buf", possibly 0 (on errors)
addraddress of the sender
addrlensize of addr
errCodevalue of errno (on errors receiving)

Definition at line 172 of file plugin_transport_tcp.c.

◆ GNUNET_SERVER_MstCreateCallback

typedef void*(* GNUNET_SERVER_MstCreateCallback) (void *cls, struct GNUNET_SERVER_Client *client)

Signature of a function to create a custom tokenizer.

Parameters
clsclosure from GNUNET_SERVER_set_callbacks
clienthandle to client the tokenzier will be used for
Returns
handle to custom tokenizer ('mst')

Definition at line 198 of file plugin_transport_tcp.c.

◆ GNUNET_SERVER_MstDestroyCallback

typedef void(* GNUNET_SERVER_MstDestroyCallback) (void *cls, void *mst)

Signature of a function to destroy a custom tokenizer.

Parameters
clsclosure from GNUNET_SERVER_set_callbacks
mstcustom tokenizer handle

Definition at line 209 of file plugin_transport_tcp.c.

◆ GNUNET_SERVER_MstReceiveCallback

typedef int(* GNUNET_SERVER_MstReceiveCallback) (void *cls, void *mst, struct GNUNET_SERVER_Client *client, const char *buf, size_t size, int purge, int one_shot)

Signature of a function to receive data for a custom tokenizer.

Parameters
clsclosure from GNUNET_SERVER_set_callbacks
mstcustom tokenizer handle
client_identityID of client for which this is a buffer, can be NULL (will be passed back to 'cb')
bufinput data to add
sizenumber of bytes in buf
purgeshould any excess bytes in the buffer be discarded (i.e. for packet-based services like UDP)
one_shotonly call callback once, keep rest of message in buffer
Returns
GNUNET_OK if we are done processing (need more data) GNUNET_NO if one_shot was set and we have another message ready GNUNET_SYSERR if the data stream is corrupt

Definition at line 227 of file plugin_transport_tcp.c.

◆ GNUNET_SERVER_MessageCallback

typedef void(* GNUNET_SERVER_MessageCallback) (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message)

Functions with this signature are called whenever a message is received.

Parameters
clsclosure
clientidentification of the client
messagethe actual message

Definition at line 243 of file plugin_transport_tcp.c.

◆ GNUNET_SERVER_MessageTokenizerCallback

typedef int(* GNUNET_SERVER_MessageTokenizerCallback) (void *cls, void *client, const struct GNUNET_MessageHeader *message)

Functions with this signature are called whenever a complete message is received by the tokenizer.

Do not call GNUNET_SERVER_mst_destroy from within the scope of this callback.

Parameters
clsclosure
clientidentification of the client
messagethe actual message
Returns
GNUNET_OK on success, GNUNET_SYSERR to stop further processing

Definition at line 339 of file plugin_transport_tcp.c.

◆ LEGACY_SERVICE_Main

typedef void(* LEGACY_SERVICE_Main) (void *cls, struct GNUNET_SERVER_Handle *server, const struct GNUNET_CONFIGURATION_Handle *cfg)

Function called by the service's run method to run service-specific setup code.

Parameters
clsclosure
serverthe initialized server
cfgconfiguration to use

Definition at line 486 of file plugin_transport_tcp.c.

Enumeration Type Documentation

◆ LEGACY_SERVICE_Options

Options for the service (bitmask).

Enumerator
LEGACY_SERVICE_OPTION_NONE 

Use defaults.

Terminates all client connections and the listen sockets immediately upon receiving the shutdown signal.

LEGACY_SERVICE_OPTION_MANUAL_SHUTDOWN 

Do not trigger server shutdown on signal at all; instead, allow for the user to terminate the server explicitly when needed by calling #LEGACY_SERVICE_shutdown().

LEGACY_SERVICE_OPTION_SOFT_SHUTDOWN 

Trigger a SOFT server shutdown on signals, allowing active non-monitor clients to complete their transactions.

Definition at line 281 of file plugin_transport_tcp.c.

281  {
287 
294 
300 };
Do not trigger server shutdown on signal at all; instead, allow for the user to terminate the server ...
Trigger a SOFT server shutdown on signals, allowing active non-monitor clients to complete their tran...

◆ TcpAddressOptions

Bits in the options field of TCP addresses.

Enumerator
TCP_OPTIONS_NONE 

No bits set.

TCP_OPTIONS_RESERVED 

See HTTP_OPTIONS_VERIFY_CERTIFICATE.

TCP_OPTIONS_TCP_STEALTH 

Enable TCP Stealth-style port knocking.

Definition at line 635 of file plugin_transport_tcp.c.

635  {
639  TCP_OPTIONS_NONE = 0,
640 
645 
650 };
See HTTP_OPTIONS_VERIFY_CERTIFICATE.
Enable TCP Stealth-style port knocking.

Function Documentation

◆ LEGACY_SERVICE_stop()

void LEGACY_SERVICE_stop ( struct LEGACY_SERVICE_Context sctx)

Stops a service that was started with GNUNET_SERVICE_start().

Parameters
srvservice to stop

Stops a service that was started with GNUNET_SERVICE_start().

Parameters
sctxthe service context returned from the start function

Definition at line 1597 of file tcp_service_legacy.c.

References LEGACY_SERVICE_Context::addrlens, LEGACY_SERVICE_Context::addrs, LEGACY_SERVICE_Context::cfg, GAUGER, GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_have_value(), GNUNET_free, GNUNET_free_non_null, GNUNET_OK, GNUNET_SCHEDULER_cancel(), GNUNET_SERVER_destroy(), GNUNET_YES, LEGACY_SERVICE_Context::my_handlers, LEGACY_SERVICE_Context::server, LEGACY_SERVICE_Context::service_name, LEGACY_SERVICE_Context::shutdown_task, LEGACY_SERVICE_Context::v4_allowed, LEGACY_SERVICE_Context::v4_denied, LEGACY_SERVICE_Context::v6_allowed, and LEGACY_SERVICE_Context::v6_denied.

Referenced by LEGACY_SERVICE_start(), libgnunet_plugin_transport_tcp_done(), and libgnunet_plugin_transport_tcp_init().

1598 {
1599  unsigned int i;
1600 
1601 #if HAVE_MALLINFO
1602  {
1603  char *counter;
1604 
1606  sctx->service_name,
1607  "GAUGER_HEAP")) &&
1609  sctx->service_name,
1610  "GAUGER_HEAP",
1611  &counter)))
1612  {
1613  struct mallinfo mi;
1614 
1615  mi = mallinfo();
1616  GAUGER(sctx->service_name, counter, mi.usmblks, "blocks");
1617  GNUNET_free(counter);
1618  }
1619  }
1620 #endif
1621  if (NULL != sctx->shutdown_task)
1622  {
1624  sctx->shutdown_task = NULL;
1625  }
1626  if (NULL != sctx->server)
1629  if (NULL != sctx->addrs)
1630  {
1631  i = 0;
1632  while (NULL != sctx->addrs[i])
1633  GNUNET_free(sctx->addrs[i++]);
1634  GNUNET_free(sctx->addrs);
1635  }
1641  GNUNET_free(sctx);
1642 }
socklen_t * addrlens
Array of the lengths of the entries in addrs.
const char * service_name
Name of our service.
struct GNUNET_SCHEDULER_Task * shutdown_task
Task ID of the shutdown task.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
struct sockaddr ** addrs
NULL-terminated array of addresses to bind to, NULL if we got pre-bound listen sockets.
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
struct GNUNET_SERVER_MessageHandler * my_handlers
My (default) message handlers.
struct GNUNET_STRINGS_IPv6NetworkPolicy * v6_allowed
IPv6 addresses that are allowed to connect (if not set, all are allowed).
int GNUNET_CONFIGURATION_have_value(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Test if we have a value for a particular option.
struct GNUNET_SERVER_Handle * server
Handle for the server.
struct GNUNET_STRINGS_IPv4NetworkPolicy * v4_allowed
IPv4 addresses that are allowed to connect (if not set, all are allowed).
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
int GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
struct GNUNET_STRINGS_IPv6NetworkPolicy * v6_denied
IPv6 addresses that are not allowed to connect.
#define GAUGER(category, counter, value, unit)
Definition: gauger.h:18
struct GNUNET_STRINGS_IPv4NetworkPolicy * v4_denied
IPv4 addresses that are not allowed to connect.
#define GNUNET_YES
Definition: gnunet_common.h:77
void GNUNET_SERVER_destroy(struct GNUNET_SERVER_Handle *server)
Free resources held by this server.
#define GNUNET_free(ptr)
Wrapper around free.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_CONNECTION_destroy()

void GNUNET_CONNECTION_destroy ( struct GNUNET_CONNECTION_Handle connection)

Close the connection and free associated resources.

There must not be any pending requests for reading or writing to the connection at this time.

Parameters
connectionconnection to destroy

Definition at line 1020 of file tcp_connection_legacy.c.

References GNUNET_CONNECTION_Handle::addr, GNUNET_CONNECTION_Handle::ap_head, GNUNET_CONNECTION_Handle::ap_tail, GNUNET_CONNECTION_Handle::destroy_later, GNUNET_CONNECTION_Handle::dns_active, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_free_non_null, GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_free_memory_only_(), GNUNET_NETWORK_socket_shutdown(), GNUNET_OK, GNUNET_RESOLVER_request_cancel(), GNUNET_SCHEDULER_cancel(), GNUNET_YES, GNUNET_CONNECTION_Handle::hostname, LOG, LOG_STRERROR, GNUNET_CONNECTION_TransmitHandle::notify_ready, GNUNET_CONNECTION_Handle::nth, GNUNET_CONNECTION_Handle::persist, GNUNET_CONNECTION_Handle::proxy_handshake, GNUNET_CONNECTION_Handle::read_task, GNUNET_CONNECTION_Handle::receiver, AddressProbe::sock, GNUNET_CONNECTION_Handle::sock, AddressProbe::task, GNUNET_CONNECTION_TransmitHandle::timeout_task, GNUNET_CONNECTION_Handle::write_buffer, GNUNET_CONNECTION_Handle::write_buffer_off, and GNUNET_CONNECTION_Handle::write_task.

Referenced by connect_fail_continuation(), GNUNET_CONNECTION_acivate_proxied(), GNUNET_SERVER_client_disconnect(), libgnunet_plugin_transport_tcp_done(), and notify_send_probe().

1021 {
1022  struct AddressProbe *pos;
1023 
1024  if (0 != connection->destroy_later)
1025  {
1026  connection->destroy_later = -1;
1027  return;
1028  }
1029  LOG(GNUNET_ERROR_TYPE_DEBUG, "Shutting down connection (%p)\n", connection);
1030  GNUNET_assert(NULL == connection->nth.notify_ready);
1031  GNUNET_assert(NULL == connection->receiver);
1032  if (NULL != connection->write_task)
1033  {
1034  GNUNET_SCHEDULER_cancel(connection->write_task);
1035  connection->write_task = NULL;
1036  connection->write_buffer_off = 0;
1037  }
1038  if (NULL != connection->read_task)
1039  {
1040  GNUNET_SCHEDULER_cancel(connection->read_task);
1041  connection->read_task = NULL;
1042  }
1043  if (NULL != connection->nth.timeout_task)
1044  {
1046  connection->nth.timeout_task = NULL;
1047  }
1048  connection->nth.notify_ready = NULL;
1049  if (NULL != connection->dns_active)
1050  {
1052  connection->dns_active = NULL;
1053  }
1054  if (NULL != connection->proxy_handshake)
1055  {
1056  /* GNUNET_CONNECTION_destroy (connection->proxy_handshake); */
1057  connection->proxy_handshake->destroy_later = -1;
1058  connection->proxy_handshake = NULL; /* Not leaked ??? */
1059  }
1060  while (NULL != (pos = connection->ap_head))
1061  {
1064  GNUNET_CONTAINER_DLL_remove(connection->ap_head, connection->ap_tail, pos);
1065  GNUNET_free(pos);
1066  }
1067  if ((NULL != connection->sock) && (GNUNET_YES != connection->persist))
1068  {
1069  if ((GNUNET_OK !=
1070  GNUNET_NETWORK_socket_shutdown(connection->sock, SHUT_RDWR)) &&
1071  (ENOTCONN != errno) && (ECONNRESET != errno))
1073  }
1074  if (NULL != connection->sock)
1075  {
1076  if (GNUNET_YES != connection->persist)
1077  {
1079  GNUNET_NETWORK_socket_close(connection->sock));
1080  }
1081  else
1082  {
1084  connection->sock); /* at least no memory leak (we deliberately
1085  * leak the socket in this special case) ... */
1086  }
1087  }
1088  GNUNET_free_non_null(connection->addr);
1089  GNUNET_free_non_null(connection->hostname);
1090  GNUNET_free(connection->write_buffer);
1091  GNUNET_free(connection);
1092 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct GNUNET_NETWORK_Handle * sock
Underlying OS's socket, set to NULL after fatal errors.
void GNUNET_RESOLVER_request_cancel(struct GNUNET_RESOLVER_RequestHandle *rh)
Cancel a request that is still pending with the resolver.
struct AddressProbe * ap_head
Linked list of sockets we are currently trying out (during connect).
struct GNUNET_CONNECTION_Handle * proxy_handshake
Handle to subsequent connection after proxy handshake completes,.
#define LOG(kind,...)
Definition: arm_api.c:33
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
struct AddressProbe * ap_tail
Linked list of sockets we are currently trying out (during connect).
struct GNUNET_SCHEDULER_Task * task
Task waiting for the connection to finish connecting.
int GNUNET_NETWORK_socket_shutdown(struct GNUNET_NETWORK_Handle *desc, int how)
Shut down socket operations.
Definition: network.c:928
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
void GNUNET_NETWORK_socket_free_memory_only_(struct GNUNET_NETWORK_Handle *desc)
Only free memory of a socket, keep the file descriptor untouched.
Definition: network.c:610
char * hostname
Pointer to the hostname if connection was created using DNS lookup, otherwise NULL.
struct GNUNET_SCHEDULER_Task * read_task
Read task that we may need to wait for.
struct sockaddr * addr
Network address of the other end-point, may be NULL.
struct GNUNET_RESOLVER_RequestHandle * dns_active
Handle to a pending DNS lookup request.
size_t write_buffer_off
Current write-offset in write_buffer (where would we write next).
struct GNUNET_NETWORK_Handle * sock
Underlying OS's socket.
int8_t persist
When shutdown, do not ever actually close the socket, but free resources.
struct GNUNET_CONNECTION_TransmitHandle nth
The handle we return for GNUNET_CONNECTION_notify_transmit_ready().
GNUNET_CONNECTION_Receiver receiver
Function to call on data received, NULL if no receive is pending.
struct GNUNET_SCHEDULER_Task * write_task
Write task that we may need to wait for.
#define GNUNET_YES
Definition: gnunet_common.h:77
char * write_buffer
Pointer to our write buffer.
GNUNET_CONNECTION_TransmitReadyNotify notify_ready
Function to call if the send buffer has notify_size bytes available.
#define LOG_STRERROR(kind, syscall)
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:548
During connect, we try multiple possible IP addresses to find out which one might work...
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_SCHEDULER_Task * timeout_task
Task called on timeout.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_SERVER_client_disconnect()

void GNUNET_SERVER_client_disconnect ( struct GNUNET_SERVER_Client client)

Ask the server to disconnect from the given client.

This is the same as passing GNUNET_SYSERR to GNUNET_SERVER_receive_done, except that it allows dropping of a client even when not handling a message from that client.

Parameters
clientthe client to disconnect from

This is the same as returning GNUNET_SYSERR from a message handler, except that it allows dropping of a client even when not handling a message from that client.

Parameters
clientthe client to disconnect from

Definition at line 1489 of file tcp_server_legacy.c.

References NotifyList::callback, NotifyList::callback_cls, GNUNET_SERVER_Handle::clients_head, GNUNET_SERVER_Handle::clients_tail, GNUNET_SERVER_Client::connection, GNUNET_SERVER_TransmitHandle::cth, GNUNET_SERVER_Handle::disconnect_notify_list_head, GNUNET_CONNECTION_destroy(), GNUNET_CONNECTION_persist_(), GNUNET_CONNECTION_receive_cancel(), GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_NO, GNUNET_SCHEDULER_cancel(), GNUNET_SERVER_mst_destroy(), GNUNET_SERVER_notify_transmit_ready_cancel(), GNUNET_YES, GNUNET_SERVER_Client::in_process_client_buffer, LOG, GNUNET_SERVER_Client::mst, GNUNET_SERVER_Handle::mst_cls, GNUNET_SERVER_Handle::mst_destroy, NotifyList::next, GNUNET_SERVER_Client::persist, GNUNET_SERVER_Client::receive_pending, GNUNET_SERVER_Client::reference_count, GNUNET_SERVER_Client::restart_task, GNUNET_SERVER_Client::server, GNUNET_SERVER_Client::shutdown_now, test_monitor_clients(), GNUNET_SERVER_Client::th, and GNUNET_SERVER_Client::warn_task.

Referenced by client_message_tokenizer_callback(), GNUNET_SERVER_client_drop(), GNUNET_SERVER_destroy(), GNUNET_SERVER_receive_done(), process_incoming(), process_mst(), and tcp_plugin_disconnect_session().

1490 {
1491  struct GNUNET_SERVER_Handle *server = client->server;
1492  struct NotifyList *n;
1493 
1495  "Client is being disconnected from the server.\n");
1496  if (NULL != client->restart_task)
1497  {
1499  client->restart_task = NULL;
1500  }
1501  if (NULL != client->warn_task)
1502  {
1504  client->warn_task = NULL;
1505  }
1506  if (GNUNET_YES == client->receive_pending)
1507  {
1509  client->receive_pending = GNUNET_NO;
1510  }
1511  client->shutdown_now = GNUNET_YES;
1512  client->reference_count++; /* make sure nobody else clean up client... */
1513  if ((NULL != client->mst) &&
1514  (NULL != server))
1515  {
1517  server->clients_tail,
1518  client);
1519  if (NULL != server->mst_destroy)
1520  server->mst_destroy(server->mst_cls,
1521  client->mst);
1522  else
1523  GNUNET_SERVER_mst_destroy(client->mst);
1524  client->mst = NULL;
1525  for (n = server->disconnect_notify_list_head; NULL != n; n = n->next)
1526  n->callback(n->callback_cls,
1527  client);
1528  }
1529  client->reference_count--;
1530  if (client->reference_count > 0)
1531  {
1533  "RC of %p still positive, not destroying everything.\n",
1534  client);
1535  client->server = NULL;
1536  return;
1537  }
1538  if (GNUNET_YES == client->in_process_client_buffer)
1539  {
1541  "Still processing inputs of %p, not destroying everything.\n",
1542  client);
1543  return;
1544  }
1546  "RC of %p now zero, destroying everything.\n",
1547  client);
1548  if (GNUNET_YES == client->persist)
1550  if (NULL != client->th.cth)
1553  /* need to cancel again, as it might have been re-added
1554  in the meantime (i.e. during callbacks) */
1555  if (NULL != client->warn_task)
1556  {
1558  client->warn_task = NULL;
1559  }
1560  if (GNUNET_YES == client->receive_pending)
1561  {
1563  client->receive_pending = GNUNET_NO;
1564  }
1565  GNUNET_free(client);
1566  /* we might be in soft-shutdown, test if we're done */
1567  if (NULL != server)
1568  test_monitor_clients(server);
1569 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
void GNUNET_CONNECTION_persist_(struct GNUNET_CONNECTION_Handle *connection)
Set the persist option on this connection handle.
int in_process_client_buffer
Are we currently in the "process_client_buffer" function (and will hence restart the receive job on e...
List of arrays of message handlers.
struct GNUNET_SERVER_Client * clients_tail
Head of list of our current clients.
#define LOG(kind,...)
Definition: arm_api.c:33
GNUNET_SERVER_MstDestroyCallback mst_destroy
Alternative function to destroy a MST instance.
GNUNET_SERVER_DisconnectCallback callback
Function to call.
#define GNUNET_NO
Definition: gnunet_common.h:78
void * GNUNET_CONNECTION_receive_cancel(struct GNUNET_CONNECTION_Handle *connection)
Cancel receive job on the given connection.
void GNUNET_SERVER_mst_destroy(struct GNUNET_SERVER_MessageStreamTokenizer *mst)
Destroys a tokenizer.
int receive_pending
Are we currently trying to receive? (GNUNET_YES if we are, GNUNET_NO if we are not, GNUNET_SYSERR if data is already available in MST).
void * callback_cls
Closure for callback.
struct NotifyList * next
This is a doubly linked list.
struct GNUNET_CONNECTION_TransmitHandle * cth
Active connection transmission handle.
struct GNUNET_SERVER_TransmitHandle th
Transmission handle we return for this client from GNUNET_SERVER_notify_transmit_ready.
void GNUNET_SERVER_notify_transmit_ready_cancel(struct GNUNET_SERVER_TransmitHandle *th)
Abort transmission request.
struct NotifyList * disconnect_notify_list_head
Head of linked list of functions to call on disconnects by clients.
handle for a server
struct GNUNET_CONNECTION_Handle * connection
Client closure for callbacks.
int shutdown_now
We're about to close down this client.
unsigned int reference_count
Number of external entities with a reference to this client object.
void GNUNET_CONNECTION_destroy(struct GNUNET_CONNECTION_Handle *connection)
Close the connection and free associated resources.
int persist
Persist the file handle for this client no matter what happens, force the OS to close once the proces...
struct GNUNET_SCHEDULER_Task * warn_task
Task that warns about missing calls to GNUNET_SERVER_receive_done.
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_SERVER_Client * clients_head
Head of list of our current clients.
static void test_monitor_clients(struct GNUNET_SERVER_Handle *server)
Check if only 'monitor' clients are left.
struct GNUNET_SERVER_Handle * server
Server that this client belongs to.
void * mst_cls
Closure for 'mst_'-callbacks.
void * mst
Processing of incoming data.
struct GNUNET_SCHEDULER_Task * restart_task
ID of task used to restart processing.
#define GNUNET_free(ptr)
Wrapper around free.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_SERVER_client_get_user_context_()

void* GNUNET_SERVER_client_get_user_context_ ( struct GNUNET_SERVER_Client client,
size_t  size 
)

Return user context associated with the given client.

Note: you should probably use the macro (call without the underscore).

Parameters
clientclient to query
sizenumber of bytes in user context struct (for verification only)
Returns
pointer to user context

Definition at line 341 of file tcp_server_legacy.c.

References GNUNET_assert, GNUNET_SERVER_Client::user_context, and GNUNET_SERVER_Client::user_context_size.

343 {
344  if ((0 == client->user_context_size) &&
345  (NULL == client->user_context))
346  return NULL; /* never set */
348  return client->user_context;
349 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
void * user_context
User context value, manipulated using 'GNUNET_SERVER_client_{get/set}_user_context' functions...
size_t user_context_size
Last size given when user context was initialized; used for sanity check.
static unsigned int size
Size of the "table".
Definition: peer.c:66

◆ GNUNET_SERVER_mst_create()

struct GNUNET_SERVER_MessageStreamTokenizer* GNUNET_SERVER_mst_create ( GNUNET_SERVER_MessageTokenizerCallback  cb,
void *  cb_cls 
)

Create a message stream tokenizer.

Parameters
cbfunction to call on completed messages
cb_clsclosure for cb
Returns
handle to tokenizer

Definition at line 83 of file tcp_server_mst_legacy.c.

References GNUNET_SERVER_MessageStreamTokenizer::cb, GNUNET_SERVER_MessageStreamTokenizer::cb_cls, GNUNET_SERVER_MessageStreamTokenizer::curr_buf, GNUNET_malloc, GNUNET_MIN_MESSAGE_SIZE, GNUNET_new, GNUNET_SERVER_MessageStreamTokenizer::hdr, and ret.

Referenced by GNUNET_SERVER_connect_socket(), and LIBGNUNET_PLUGIN_TRANSPORT_INIT().

85 {
87 
91  ret->cb = cb;
92  ret->cb_cls = cb_cls;
93  return ret;
94 }
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static int ret
Final status code.
Definition: gnunet-arm.c:89
Handle to a message stream tokenizer.
#define GNUNET_MIN_MESSAGE_SIZE
Smallest supported message.
struct GNUNET_MessageHeader * hdr
Beginning of the buffer.
GNUNET_SERVER_MessageTokenizerCallback cb
Function to call on completed messages.
size_t curr_buf
Size of the buffer (starting at hdr).
#define GNUNET_malloc(size)
Wrapper around malloc.
Here is the caller graph for this function:

◆ GNUNET_SERVER_mst_receive()

int GNUNET_SERVER_mst_receive ( struct GNUNET_SERVER_MessageStreamTokenizer mst,
void *  client_identity,
const char *  buf,
size_t  size,
int  purge,
int  one_shot 
)

Add incoming data to the receive buffer and call the callback for all complete messages.

Parameters
msttokenizer to use
client_identityID of client for which this is a buffer, can be NULL (will be passed back to 'cb')
bufinput data to add
sizenumber of bytes in buf
purgeshould any excess bytes in the buffer be discarded (i.e. for packet-based services like UDP)
one_shotonly call callback once, keep rest of message in buffer
Returns
GNUNET_OK if we are done processing (need more data) GNUNET_NO if one_shot was set and we have another message ready GNUNET_SYSERR if the data stream is corrupt
Parameters
msttokenizer to use
client_identityID of client for which this is a buffer
bufinput data to add
sizenumber of bytes in buf
purgeshould any excess bytes in the buffer be discarded (i.e. for packet-based services like UDP)
one_shotonly call callback once, keep rest of message in buffer
Returns
GNUNET_OK if we are done processing (need more data) GNUNET_NO if one_shot was set and we have another message ready GNUNET_SYSERR if the data stream is corrupt

Definition at line 113 of file tcp_server_mst_legacy.c.

References ALIGN_FACTOR, GNUNET_SERVER_MessageStreamTokenizer::cb, GNUNET_SERVER_MessageStreamTokenizer::cb_cls, GNUNET_SERVER_MessageStreamTokenizer::curr_buf, delta, do_align(), GNUNET_assert, GNUNET_break_op, GNUNET_ERROR_TYPE_DEBUG, GNUNET_memcpy, GNUNET_MIN, GNUNET_NO, GNUNET_OK, GNUNET_realloc, GNUNET_SYSERR, GNUNET_YES, GNUNET_SERVER_MessageStreamTokenizer::hdr, LOG, GNUNET_SERVER_MessageStreamTokenizer::off, GNUNET_SERVER_MessageStreamTokenizer::pos, ret, size, and GNUNET_MessageHeader::size.

Referenced by handle_helper_message(), process_data(), process_incoming(), process_mst(), and wlan_data_message_handler().

117 {
118  const struct GNUNET_MessageHeader *hdr;
119  size_t delta;
120  uint16_t want;
121  char *ibuf;
122  int need_align;
123  unsigned long offset;
124  int ret;
125 
126  GNUNET_assert(mst->off <= mst->pos);
127  GNUNET_assert(mst->pos <= mst->curr_buf);
129  "Server-mst receives %u bytes with %u bytes already in private buffer\n",
130  (unsigned int)size, (unsigned int)(mst->pos - mst->off));
131  ret = GNUNET_OK;
132  ibuf = (char *)mst->hdr;
133  while (mst->pos > 0)
134  {
135 do_align:
136  GNUNET_assert(mst->pos >= mst->off);
137  if ((mst->curr_buf - mst->off < sizeof(struct GNUNET_MessageHeader)) ||
138  (0 != (mst->off % ALIGN_FACTOR)))
139  {
140  /* need to align or need more space */
141  mst->pos -= mst->off;
142  memmove(ibuf, &ibuf[mst->off], mst->pos);
143  mst->off = 0;
144  }
145  if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader))
146  {
147  delta =
148  GNUNET_MIN(sizeof(struct GNUNET_MessageHeader) -
149  (mst->pos - mst->off), size);
150  GNUNET_memcpy(&ibuf[mst->pos], buf, delta);
151  mst->pos += delta;
152  buf += delta;
153  size -= delta;
154  }
155  if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader))
156  {
157  if (purge)
158  {
159  mst->off = 0;
160  mst->pos = 0;
161  }
162  return GNUNET_OK;
163  }
164  hdr = (const struct GNUNET_MessageHeader *)&ibuf[mst->off];
165  want = ntohs(hdr->size);
166  if (want < sizeof(struct GNUNET_MessageHeader))
167  {
168  GNUNET_break_op(0);
169  return GNUNET_SYSERR;
170  }
171  if ((mst->curr_buf - mst->off < want) &&
172  (mst->off > 0))
173  {
174  /* can get more space by moving */
175  mst->pos -= mst->off;
176  memmove(ibuf, &ibuf[mst->off], mst->pos);
177  mst->off = 0;
178  }
179  if (mst->curr_buf < want)
180  {
181  /* need to get more space by growing buffer */
182  GNUNET_assert(0 == mst->off);
183  mst->hdr = GNUNET_realloc(mst->hdr, want);
184  ibuf = (char *)mst->hdr;
185  mst->curr_buf = want;
186  }
187  hdr = (const struct GNUNET_MessageHeader *)&ibuf[mst->off];
188  if (mst->pos - mst->off < want)
189  {
190  delta = GNUNET_MIN(want - (mst->pos - mst->off), size);
191  GNUNET_assert(mst->pos + delta <= mst->curr_buf);
192  GNUNET_memcpy(&ibuf[mst->pos], buf, delta);
193  mst->pos += delta;
194  buf += delta;
195  size -= delta;
196  }
197  if (mst->pos - mst->off < want)
198  {
199  if (purge)
200  {
201  mst->off = 0;
202  mst->pos = 0;
203  }
204  return GNUNET_OK;
205  }
206  if (one_shot == GNUNET_SYSERR)
207  {
208  /* cannot call callback again, but return value saying that
209  * we have another full message in the buffer */
210  ret = GNUNET_NO;
211  goto copy;
212  }
213  if (one_shot == GNUNET_YES)
214  one_shot = GNUNET_SYSERR;
215  mst->off += want;
216  if (GNUNET_SYSERR == mst->cb(mst->cb_cls, client_identity, hdr))
217  return GNUNET_SYSERR;
218  if (mst->off == mst->pos)
219  {
220  /* reset to beginning of buffer, it's free right now! */
221  mst->off = 0;
222  mst->pos = 0;
223  }
224  }
225  GNUNET_assert(0 == mst->pos);
226  while (size > 0)
227  {
229  "Server-mst has %u bytes left in inbound buffer\n",
230  (unsigned int)size);
231  if (size < sizeof(struct GNUNET_MessageHeader))
232  break;
233  offset = (unsigned long)buf;
234  need_align = (0 != (offset % ALIGN_FACTOR)) ? GNUNET_YES : GNUNET_NO;
235  if (GNUNET_NO == need_align)
236  {
237  /* can try to do zero-copy and process directly from original buffer */
238  hdr = (const struct GNUNET_MessageHeader *)buf;
239  want = ntohs(hdr->size);
240  if (want < sizeof(struct GNUNET_MessageHeader))
241  {
242  GNUNET_break_op(0);
243  mst->off = 0;
244  return GNUNET_SYSERR;
245  }
246  if (size < want)
247  break; /* or not: buffer incomplete, so copy to private buffer... */
248  if (one_shot == GNUNET_SYSERR)
249  {
250  /* cannot call callback again, but return value saying that
251  * we have another full message in the buffer */
252  ret = GNUNET_NO;
253  goto copy;
254  }
255  if (one_shot == GNUNET_YES)
256  one_shot = GNUNET_SYSERR;
257  if (GNUNET_SYSERR == mst->cb(mst->cb_cls, client_identity, hdr))
258  return GNUNET_SYSERR;
259  buf += want;
260  size -= want;
261  }
262  else
263  {
264  /* need to copy to private buffer to align;
265  * yes, we go a bit more spagetti than usual here */
266  goto do_align;
267  }
268  }
269 copy:
270  if ((size > 0) && (!purge))
271  {
272  if (size + mst->pos > mst->curr_buf)
273  {
274  mst->hdr = GNUNET_realloc(mst->hdr, size + mst->pos);
275  ibuf = (char *)mst->hdr;
276  mst->curr_buf = size + mst->pos;
277  }
278  GNUNET_assert(size + mst->pos <= mst->curr_buf);
279  GNUNET_memcpy(&ibuf[mst->pos], buf, size);
280  mst->pos += size;
281  }
282  if (purge)
283  {
284  mst->off = 0;
285  mst->pos = 0;
286  }
288  "Server-mst leaves %u bytes in private buffer\n",
289  (unsigned int)(mst->pos - mst->off));
290  return ret;
291 }
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
#define ALIGN_FACTOR
static size_t do_align(size_t start_position, size_t end_position)
Given the start and end position of a block of data, return the end position of that data after align...
Definition: fs_directory.c:480
#define LOG(kind,...)
Definition: arm_api.c:33
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
size_t pos
How many bytes in buffer are valid right now?
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
static int ret
Final status code.
Definition: gnunet-arm.c:89
size_t off
How many bytes in buffer have we already processed?
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_realloc(ptr, size)
Wrapper around realloc.
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:80
static char buf[2048]
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned int size
Size of the "table".
Definition: peer.c:66
struct GNUNET_MessageHeader * hdr
Beginning of the buffer.
GNUNET_SERVER_MessageTokenizerCallback cb
Function to call on completed messages.
size_t curr_buf
Size of the buffer (starting at hdr).
Header for all communications.
#define GNUNET_YES
Definition: gnunet_common.h:77
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_SERVER_mst_destroy()

void GNUNET_SERVER_mst_destroy ( struct GNUNET_SERVER_MessageStreamTokenizer mst)

Destroys a tokenizer.

Parameters
msttokenizer to destroy

Definition at line 300 of file tcp_server_mst_legacy.c.

References GNUNET_free, and GNUNET_SERVER_MessageStreamTokenizer::hdr.

Referenced by GNUNET_SERVER_client_disconnect(), and LIBGNUNET_PLUGIN_TRANSPORT_DONE().

301 {
302  GNUNET_free(mst->hdr);
303  GNUNET_free(mst);
304 }
struct GNUNET_MessageHeader * hdr
Beginning of the buffer.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the caller graph for this function:

◆ GNUNET_SERVER_client_set_user_context_()

void GNUNET_SERVER_client_set_user_context_ ( struct GNUNET_SERVER_Client client,
void *  ptr,
size_t  size 
)

Set user context to be associated with the given client.

Note: you should probably use the macro (call without the underscore).

Parameters
clientclient to query
ptrpointer to user context
sizenumber of bytes in user context struct (for verification only)

Definition at line 361 of file tcp_server_legacy.c.

References size, GNUNET_SERVER_Client::user_context, and GNUNET_SERVER_Client::user_context_size.

364 {
365  if (NULL == ptr)
366  {
367  client->user_context_size = 0;
368  client->user_context = ptr;
369  return;
370  }
371  client->user_context_size = size;
372  client->user_context = ptr;
373 }
void * user_context
User context value, manipulated using &#39;GNUNET_SERVER_client_{get/set}_user_context&#39; functions...
size_t user_context_size
Last size given when user context was initialized; used for sanity check.
static unsigned int size
Size of the "table".
Definition: peer.c:66

◆ GNUNET_SERVER_notify_transmit_ready()

struct GNUNET_SERVER_TransmitHandle * GNUNET_SERVER_notify_transmit_ready ( struct GNUNET_SERVER_Client client,
size_t  size,
struct GNUNET_TIME_Relative  timeout,
GNUNET_CONNECTION_TransmitReadyNotify  callback,
void *  callback_cls 
)

Notify us when the server has enough space to transmit a message of the given size to the given client.

Parameters
clientclient to transmit message to
sizerequested amount of buffer space
timeoutafter how long should we give up (and call notify with buf NULL and size 0)?
callbackfunction to call when space is available
callback_clsclosure for callback
Returns
non-NULL if the notify callback was queued; can be used to cancel the request using GNUNET_SERVER_notify_transmit_ready_cancel. NULL if we are already going to notify someone else (busy)
Parameters
clientclient to transmit message to
sizerequested amount of buffer space
timeoutafter how long should we give up (and call notify with buf NULL and size 0)?
callbackfunction to call when space is available
callback_clsclosure for callback
Returns
non-NULL if the notify callback was queued; can be used to cancel the request using GNUNET_SERVER_notify_transmit_ready_cancel(). NULL if we are already going to notify someone else (busy)

Definition at line 1626 of file tcp_server_legacy.c.

References GNUNET_SERVER_TransmitHandle::callback, GNUNET_SERVER_TransmitHandle::callback_cls, GNUNET_SERVER_Client::connection, GNUNET_SERVER_TransmitHandle::cth, GNUNET_CONNECTION_notify_transmit_ready(), GNUNET_SERVER_Client::th, and transmit_ready_callback_wrapper().

Referenced by handle_test(), and process_pending_messages().

1631 {
1632  if (NULL != client->th.callback)
1633  return NULL;
1634  client->th.callback_cls = callback_cls;
1635  client->th.callback = callback;
1637  timeout,
1639  client);
1640  return &client->th;
1641 }
struct GNUNET_CONNECTION_TransmitHandle * cth
Active connection transmission handle.
struct GNUNET_SERVER_TransmitHandle th
Transmission handle we return for this client from GNUNET_SERVER_notify_transmit_ready.
struct GNUNET_CONNECTION_Handle * connection
Client closure for callbacks.
static unsigned int size
Size of the "table".
Definition: peer.c:66
GNUNET_CONNECTION_TransmitReadyNotify callback
Function to call to get the message.
struct GNUNET_CONNECTION_TransmitHandle * GNUNET_CONNECTION_notify_transmit_ready(struct GNUNET_CONNECTION_Handle *connection, size_t size, struct GNUNET_TIME_Relative timeout, GNUNET_CONNECTION_TransmitReadyNotify notify, void *notify_cls)
Ask the connection to call us once the specified number of bytes are free in the transmission buffer...
void * callback_cls
Closure for callback.
static size_t transmit_ready_callback_wrapper(void *cls, size_t size, void *buf)
Wrapper for transmission notification that calls the original callback and update the last activity t...
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_SERVER_notify_transmit_ready_cancel()

void GNUNET_SERVER_notify_transmit_ready_cancel ( struct GNUNET_SERVER_TransmitHandle th)

Abort transmission request.

Parameters
threquest to abort

Definition at line 1650 of file tcp_server_legacy.c.

References GNUNET_SERVER_TransmitHandle::callback, GNUNET_SERVER_TransmitHandle::cth, and GNUNET_CONNECTION_notify_transmit_ready_cancel().

Referenced by GNUNET_SERVER_client_disconnect(), and tcp_plugin_disconnect_session().

1651 {
1653  th->cth = NULL;
1654  th->callback = NULL;
1655 }
void GNUNET_CONNECTION_notify_transmit_ready_cancel(struct GNUNET_CONNECTION_TransmitHandle *th)
Cancel the specified transmission-ready notification.
struct GNUNET_CONNECTION_TransmitHandle * cth
Active connection transmission handle.
GNUNET_CONNECTION_TransmitReadyNotify callback
Function to call to get the message.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_SERVER_client_keep()

void GNUNET_SERVER_client_keep ( struct GNUNET_SERVER_Client client)

Notify the server that the given client handle should be kept (keeps the connection up if possible, increments the internal reference counter).

Parameters
clientthe client to keep

Definition at line 1324 of file tcp_server_legacy.c.

References GNUNET_SERVER_Client::reference_count.

Referenced by process_incoming(), and restart_processing().

1325 {
1326  client->reference_count++;
1327 }
unsigned int reference_count
Number of external entities with a reference to this client object.
Here is the caller graph for this function:

◆ GNUNET_SERVER_client_drop()

void GNUNET_SERVER_client_drop ( struct GNUNET_SERVER_Client client)

Notify the server that the given client handle is no longer required.

Decrements the reference counter. If that counter reaches zero an inactive connection maybe closed.

Parameters
clientthe client to drop

Definition at line 1339 of file tcp_server_legacy.c.

References GNUNET_assert, GNUNET_SERVER_client_disconnect(), GNUNET_YES, GNUNET_SERVER_Client::reference_count, and GNUNET_SERVER_Client::shutdown_now.

Referenced by process_incoming(), and restart_processing().

1340 {
1341  GNUNET_assert(client->reference_count > 0);
1342  client->reference_count--;
1343  if ((GNUNET_YES == client->shutdown_now) && (0 == client->reference_count))
1345 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
int shutdown_now
We&#39;re about to close down this client.
unsigned int reference_count
Number of external entities with a reference to this client object.
void GNUNET_SERVER_client_disconnect(struct GNUNET_SERVER_Client *client)
Ask the server to disconnect from the given client.
#define GNUNET_YES
Definition: gnunet_common.h:77
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_SERVER_suspend()

void GNUNET_SERVER_suspend ( struct GNUNET_SERVER_Handle server)

Suspend accepting connections from the listen socket temporarily.

Resume activity using GNUNET_SERVER_resume.

Parameters
serverserver to stop accepting connections.
serverserver to stop accepting connections.

Definition at line 684 of file tcp_server_legacy.c.

References GNUNET_SCHEDULER_cancel(), and GNUNET_SERVER_Handle::listen_task.

Referenced by connect_notify().

685 {
686  if (NULL != server->listen_task)
687  {
689  server->listen_task = NULL;
690  }
691 }
struct GNUNET_SCHEDULER_Task * listen_task
Task scheduled to do the listening.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_SERVER_connect_socket()

struct GNUNET_SERVER_Client* GNUNET_SERVER_connect_socket ( struct GNUNET_SERVER_Handle server,
struct GNUNET_CONNECTION_Handle connection 
)

Add a TCP socket-based connection to the set of handles managed by this server.

Use this function for outgoing (P2P) connections that we initiated (and where this server should process incoming messages).

Parameters
serverthe server to use
connectionthe connection to manage (client must stop using this connection from now on)
Returns
the client handle

Definition at line 1264 of file tcp_server_legacy.c.

References NotifyList::callback, NotifyList::callback_cls, client_message_tokenizer_callback(), GNUNET_SERVER_Handle::clients_head, GNUNET_SERVER_Handle::clients_tail, GNUNET_SERVER_Handle::connect_notify_list_head, GNUNET_SERVER_Client::connection, GNUNET_assert, GNUNET_CONNECTION_receive(), GNUNET_CONTAINER_DLL_insert, GNUNET_MAX_MESSAGE_SIZE, GNUNET_new, GNUNET_SERVER_mst_create(), GNUNET_SYSERR, GNUNET_TIME_absolute_get(), GNUNET_YES, GNUNET_SERVER_Handle::idle_timeout, GNUNET_SERVER_Client::idle_timeout, GNUNET_SERVER_Client::last_activity, GNUNET_SERVER_Client::mst, GNUNET_SERVER_Handle::mst_cls, GNUNET_SERVER_Handle::mst_create, NotifyList::next, process_incoming(), GNUNET_SERVER_Client::receive_pending, and GNUNET_SERVER_Client::server.

Referenced by notify_send_probe(), process_listen_socket(), and tcp_plugin_get_session().

1266 {
1267  struct GNUNET_SERVER_Client *client;
1268  struct NotifyList *n;
1269 
1270  client = GNUNET_new(struct GNUNET_SERVER_Client);
1271  client->connection = connection;
1272  client->server = server;
1274  client->idle_timeout = server->idle_timeout;
1276  server->clients_tail,
1277  client);
1278  if (NULL != server->mst_create)
1279  client->mst =
1280  server->mst_create(server->mst_cls, client);
1281  else
1282  client->mst =
1284  server);
1285  GNUNET_assert(NULL != client->mst);
1286  for (n = server->connect_notify_list_head; NULL != n; n = n->next)
1287  n->callback(n->callback_cls, client);
1288  client->receive_pending = GNUNET_YES;
1289  if (GNUNET_SYSERR ==
1292  client->idle_timeout,
1294  client))
1295  return NULL;
1296  return client;
1297 }
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
struct NotifyList * connect_notify_list_head
Head of linked list of functions to call on connects by clients.
List of arrays of message handlers.
struct GNUNET_SERVER_Client * clients_tail
Head of list of our current clients.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_TIME_Absolute last_activity
Last activity on this socket (used to time it out if reference_count == 0).
GNUNET_SERVER_DisconnectCallback callback
Function to call.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
int receive_pending
Are we currently trying to receive? (GNUNET_YES if we are, GNUNET_NO if we are not, GNUNET_SYSERR if data is already available in MST).
void * callback_cls
Closure for callback.
struct NotifyList * next
This is a doubly linked list.
struct GNUNET_TIME_Relative idle_timeout
After how long should an idle connection time out (on write).
struct GNUNET_TIME_Relative idle_timeout
After how long should an idle connection time out (on write).
int GNUNET_CONNECTION_receive(struct GNUNET_CONNECTION_Handle *connection, size_t max, struct GNUNET_TIME_Relative timeout, GNUNET_CONNECTION_Receiver receiver, void *receiver_cls)
Receive data from the given connection.
GNUNET_SERVER_MstCreateCallback mst_create
Alternative function to create a MST instance.
struct GNUNET_CONNECTION_Handle * connection
Client closure for callbacks.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
static void process_incoming(void *cls, const void *buf, size_t available, const struct sockaddr *addr, socklen_t addrlen, int errCode)
We are receiving an incoming message.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static int client_message_tokenizer_callback(void *cls, void *client, const struct GNUNET_MessageHeader *message)
This function is called whenever our inbound message tokenizer has received a complete message...
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
#define GNUNET_YES
Definition: gnunet_common.h:77
handle for a client of the server
struct GNUNET_SERVER_Client * clients_head
Head of list of our current clients.
struct GNUNET_SERVER_Handle * server
Server that this client belongs to.
void * mst_cls
Closure for &#39;mst_&#39;-callbacks.
void * mst
Processing of incoming data.
struct GNUNET_SERVER_MessageStreamTokenizer * GNUNET_SERVER_mst_create(GNUNET_SERVER_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_SERVER_resume()

void GNUNET_SERVER_resume ( struct GNUNET_SERVER_Handle server)

Resume accepting connections from the listen socket.

Parameters
serverserver to resume accepting connections.
serverserver to stop accepting connections.

Definition at line 700 of file tcp_server_legacy.c.

References GNUNET_NETWORK_fdset_create(), GNUNET_NETWORK_fdset_destroy(), GNUNET_NETWORK_fdset_set(), GNUNET_SCHEDULER_add_read_net_with_priority(), GNUNET_SCHEDULER_add_select(), GNUNET_SCHEDULER_PRIORITY_HIGH, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_SERVER_Handle::listen_sockets, GNUNET_SERVER_Handle::listen_task, and process_listen_socket().

Referenced by disconnect_notify(), GNUNET_SERVER_create_with_sockets(), and process_listen_socket().

701 {
702  struct GNUNET_NETWORK_FDSet *r;
703  unsigned int i;
704 
705  if (NULL == server->listen_sockets)
706  return;
707  if (NULL == server->listen_sockets[0])
708  return; /* nothing to do, no listen sockets! */
709  if (NULL == server->listen_sockets[1])
710  {
711  /* simplified method: no fd set needed; this is then much simpler
712  and much more efficient */
713  server->listen_task =
716  server->listen_sockets[0],
717  &process_listen_socket, server);
718  return;
719  }
721  i = 0;
722  while (NULL != server->listen_sockets[i])
723  GNUNET_NETWORK_fdset_set(r, server->listen_sockets[i++]);
724  server->listen_task =
727  &process_listen_socket, server);
729 }
Run with high priority (important requests).
struct GNUNET_NETWORK_Handle ** listen_sockets
NULL-terminated array of sockets used to listen for new connections.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_net_with_priority(struct GNUNET_TIME_Relative delay, enum GNUNET_SCHEDULER_Priority priority, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified priority and to be run after the specified delay or wh...
Definition: scheduler.c:1501
void GNUNET_NETWORK_fdset_destroy(struct GNUNET_NETWORK_FDSet *fds)
Releases the associated memory of an fd set.
Definition: network.c:1254
struct GNUNET_NETWORK_FDSet * GNUNET_NETWORK_fdset_create(void)
Creates an fd set.
Definition: network.c:1238
collection of IO descriptors
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_select(enum GNUNET_SCHEDULER_Priority prio, struct GNUNET_TIME_Relative delay, const struct GNUNET_NETWORK_FDSet *rs, const struct GNUNET_NETWORK_FDSet *ws, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when any of the specified file descriptor set...
Definition: scheduler.c:1784
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
static void process_listen_socket(void *cls)
Scheduler says our listen socket is ready.
void GNUNET_NETWORK_fdset_set(struct GNUNET_NETWORK_FDSet *fds, const struct GNUNET_NETWORK_Handle *desc)
Add a socket to the FD set.
Definition: network.c:999
struct GNUNET_SCHEDULER_Task * listen_task
Task scheduled to do the listening.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_SERVER_destroy()

void GNUNET_SERVER_destroy ( struct GNUNET_SERVER_Handle server)

Free resources held by this server.

Parameters
serverserver to destroy

Definition at line 771 of file tcp_server_legacy.c.

References NotifyList::callback, NotifyList::callback_cls, GNUNET_SERVER_Handle::clients_head, GNUNET_SERVER_Handle::connect_notify_list_head, GNUNET_SERVER_Handle::connect_notify_list_tail, GNUNET_SERVER_Handle::disconnect_notify_list_head, GNUNET_SERVER_Handle::disconnect_notify_list_tail, GNUNET_break, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_NETWORK_socket_close(), GNUNET_OK, GNUNET_SCHEDULER_cancel(), GNUNET_SERVER_client_disconnect(), GNUNET_SERVER_Handle::handlers, GNUNET_SERVER_Handle::listen_sockets, GNUNET_SERVER_Handle::listen_task, LOG, and HandlerList::next.

Referenced by do_destroy(), LEGACY_SERVICE_stop(), libgnunet_plugin_transport_tcp_done(), and shutdown_task().

772 {
773  struct HandlerList *hpos;
774  struct NotifyList *npos;
775  unsigned int i;
776 
778  "Server shutting down.\n");
779  if (NULL != server->listen_task)
780  {
782  server->listen_task = NULL;
783  }
784  if (NULL != server->listen_sockets)
785  {
786  i = 0;
787  while (NULL != server->listen_sockets[i])
790  GNUNET_free(server->listen_sockets);
791  server->listen_sockets = NULL;
792  }
793  while (NULL != server->clients_head)
795  while (NULL != (hpos = server->handlers))
796  {
797  server->handlers = hpos->next;
798  GNUNET_free(hpos);
799  }
800  while (NULL != (npos = server->disconnect_notify_list_head))
801  {
802  npos->callback(npos->callback_cls,
803  NULL);
806  npos);
807  GNUNET_free(npos);
808  }
809  while (NULL != (npos = server->connect_notify_list_head))
810  {
811  npos->callback(npos->callback_cls,
812  NULL);
814  server->connect_notify_list_tail,
815  npos);
816  GNUNET_free(npos);
817  }
818  GNUNET_free(server);
819 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
List of arrays of message handlers.
struct NotifyList * connect_notify_list_head
Head of linked list of functions to call on connects by clients.
List of arrays of message handlers.
struct GNUNET_NETWORK_Handle ** listen_sockets
NULL-terminated array of sockets used to listen for new connections.
#define LOG(kind,...)
Definition: arm_api.c:33
GNUNET_SERVER_DisconnectCallback callback
Function to call.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
void * callback_cls
Closure for callback.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct HandlerList * handlers
List of handlers for incoming messages.
struct NotifyList * disconnect_notify_list_head
Head of linked list of functions to call on disconnects by clients.
void GNUNET_SERVER_client_disconnect(struct GNUNET_SERVER_Client *client)
Ask the server to disconnect from the given client.
struct GNUNET_SCHEDULER_Task * listen_task
Task scheduled to do the listening.
struct NotifyList * disconnect_notify_list_tail
Tail of linked list of functions to call on disconnects by clients.
struct NotifyList * connect_notify_list_tail
Tail of linked list of functions to call on connects by clients.
struct GNUNET_SERVER_Client * clients_head
Head of list of our current clients.
struct HandlerList * next
This is a linked list.
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:548
#define GNUNET_free(ptr)
Wrapper around free.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_server_addresses()

static int get_server_addresses ( const char *  service_name,
const struct GNUNET_CONFIGURATION_Handle cfg,
struct sockaddr ***  addrs,
socklen_t **  addr_lens 
)
static

Get the list of addresses that a server for the given service should bind to.

Parameters
service_namename of the service
cfgconfiguration (which specifies the addresses)
addrsset (call by reference) to an array of pointers to the addresses the server should bind to and listen on; the array will be NULL-terminated (on success)
addr_lensset (call by reference) to an array of the lengths of the respective struct sockaddr struct in the addrs array (on success)
Returns
number of addresses found on success, GNUNET_SYSERR if the configuration did not specify reasonable finding information or if it specified a hostname that could not be resolved; GNUNET_NO if the number of addresses configured is zero (in this case, *addrs and *addr_lens will be set to NULL).

Definition at line 1039 of file plugin_transport_tcp.c.

References _, add_unixpath(), GNUNET_a2s(), GNUNET_assert, GNUNET_break, GNUNET_CONFIGURATION_get_value_filename(), GNUNET_CONFIGURATION_get_value_number(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_CONFIGURATION_have_value(), GNUNET_DISK_directory_create_for_file(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_free_non_null, GNUNET_log_strerror, GNUNET_log_strerror_file, GNUNET_malloc, GNUNET_memcpy, GNUNET_NETWORK_shorten_unixpath(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_create(), GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, hostname, LOG, port, res, and ret.

Referenced by libgnunet_plugin_transport_tcp_init().

1043 {
1044  int disablev6;
1045  struct GNUNET_NETWORK_Handle *desc;
1046  unsigned long long port;
1047  char *unixpath;
1048  struct addrinfo hints;
1049  struct addrinfo *res;
1050  struct addrinfo *pos;
1051  struct addrinfo *next;
1052  unsigned int i;
1053  int resi;
1054  int ret;
1055  int abstract;
1056  struct sockaddr **saddrs;
1057  socklen_t *saddrlens;
1058  char *hostname;
1059 
1060  *addrs = NULL;
1061  *addr_lens = NULL;
1062  desc = NULL;
1063  if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "DISABLEV6"))
1064  {
1065  if (GNUNET_SYSERR ==
1066  (disablev6 = GNUNET_CONFIGURATION_get_value_yesno(cfg,
1067  service_name,
1068  "DISABLEV6")))
1069  return GNUNET_SYSERR;
1070  }
1071  else
1072  disablev6 = GNUNET_NO;
1073 
1074  if (!disablev6)
1075  {
1076  /* probe IPv6 support */
1077  desc = GNUNET_NETWORK_socket_create(PF_INET6, SOCK_STREAM, 0);
1078  if (NULL == desc)
1079  {
1080  if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
1081  (EACCES == errno))
1082  {
1084  return GNUNET_SYSERR;
1085  }
1087  _(
1088  "Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
1089  service_name,
1090  strerror(errno));
1091  disablev6 = GNUNET_YES;
1092  }
1093  else
1094  {
1096  desc = NULL;
1097  }
1098  }
1099 
1100  port = 0;
1102  {
1104  service_name,
1105  "PORT",
1106  &port))
1107  {
1109  _("Require valid port number for service `%s' in configuration!\n"),
1110  service_name);
1111  }
1112  if (port > 65535)
1113  {
1115  _("Require valid port number for service `%s' in configuration!\n"),
1116  service_name);
1117  return GNUNET_SYSERR;
1118  }
1119  }
1120 
1121  if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "BINDTO"))
1122  {
1125  service_name,
1126  "BINDTO",
1127  &hostname));
1128  }
1129  else
1130  hostname = NULL;
1131 
1132  unixpath = NULL;
1133  abstract = GNUNET_NO;
1134 #ifdef AF_UNIX
1135  if ((GNUNET_YES ==
1136  GNUNET_CONFIGURATION_have_value(cfg, service_name, "UNIXPATH")) &&
1138  service_name,
1139  "UNIXPATH",
1140  &unixpath)) &&
1141  (0 < strlen(unixpath)))
1142  {
1143  /* probe UNIX support */
1144  struct sockaddr_un s_un;
1145 
1146  if (strlen(unixpath) >= sizeof(s_un.sun_path))
1147  {
1149  _("UNIXPATH `%s' too long, maximum length is %llu\n"),
1150  unixpath,
1151  (unsigned long long)sizeof(s_un.sun_path));
1152  unixpath = GNUNET_NETWORK_shorten_unixpath(unixpath);
1153  LOG(GNUNET_ERROR_TYPE_INFO, _("Using `%s' instead\n"), unixpath);
1154  }
1155 #ifdef LINUX
1156  abstract = GNUNET_CONFIGURATION_get_value_yesno(cfg,
1157  "TESTING",
1158  "USE_ABSTRACT_SOCKETS");
1159  if (GNUNET_SYSERR == abstract)
1160  abstract = GNUNET_NO;
1161 #endif
1162  if ((GNUNET_YES != abstract) &&
1165  }
1166  if (NULL != unixpath)
1167  {
1168  desc = GNUNET_NETWORK_socket_create(AF_UNIX, SOCK_STREAM, 0);
1169  if (NULL == desc)
1170  {
1171  if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
1172  (EACCES == errno))
1173  {
1175  GNUNET_free_non_null(hostname);
1176  GNUNET_free(unixpath);
1177  return GNUNET_SYSERR;
1178  }
1180  _(
1181  "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
1182  service_name,
1183  strerror(errno));
1184  GNUNET_free(unixpath);
1185  unixpath = NULL;
1186  }
1187  else
1188  {
1190  desc = NULL;
1191  }
1192  }
1193 #endif
1194 
1195  if ((0 == port) && (NULL == unixpath))
1196  {
1198  _(
1199  "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
1200  service_name);
1201  GNUNET_free_non_null(hostname);
1202  return GNUNET_SYSERR;
1203  }
1204  if (0 == port)
1205  {
1206  saddrs = GNUNET_malloc(2 * sizeof(struct sockaddr *));
1207  saddrlens = GNUNET_malloc(2 * sizeof(socklen_t));
1208  add_unixpath(saddrs, saddrlens, unixpath, abstract);
1209  GNUNET_free_non_null(unixpath);
1210  GNUNET_free_non_null(hostname);
1211  *addrs = saddrs;
1212  *addr_lens = saddrlens;
1213  return 1;
1214  }
1215 
1216  if (NULL != hostname)
1217  {
1219  "Resolving `%s' since that is where `%s' will bind to.\n",
1220  hostname,
1221  service_name);
1222  memset(&hints, 0, sizeof(struct addrinfo));
1223  if (disablev6)
1224  hints.ai_family = AF_INET;
1225  hints.ai_protocol = IPPROTO_TCP;
1226  if ((0 != (ret = getaddrinfo(hostname, NULL, &hints, &res))) ||
1227  (NULL == res))
1228  {
1230  _("Failed to resolve `%s': %s\n"),
1231  hostname,
1232  gai_strerror(ret));
1233  GNUNET_free(hostname);
1234  GNUNET_free_non_null(unixpath);
1235  return GNUNET_SYSERR;
1236  }
1237  next = res;
1238  i = 0;
1239  while (NULL != (pos = next))
1240  {
1241  next = pos->ai_next;
1242  if ((disablev6) && (pos->ai_family == AF_INET6))
1243  continue;
1244  i++;
1245  }
1246  if (0 == i)
1247  {
1249  _("Failed to find %saddress for `%s'.\n"),
1250  disablev6 ? "IPv4 " : "",
1251  hostname);
1252  freeaddrinfo(res);
1253  GNUNET_free(hostname);
1254  GNUNET_free_non_null(unixpath);
1255  return GNUNET_SYSERR;
1256  }
1257  resi = i;
1258  if (NULL != unixpath)
1259  resi++;
1260  saddrs = GNUNET_malloc((resi + 1) * sizeof(struct sockaddr *));
1261  saddrlens = GNUNET_malloc((resi + 1) * sizeof(socklen_t));
1262  i = 0;
1263  if (NULL != unixpath)
1264  {
1265  add_unixpath(saddrs, saddrlens, unixpath, abstract);
1266  i++;
1267  }
1268  next = res;
1269  while (NULL != (pos = next))
1270  {
1271  next = pos->ai_next;
1272  if ((disablev6) && (AF_INET6 == pos->ai_family))
1273  continue;
1274  if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol))
1275  continue; /* not TCP */
1276  if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype))
1277  continue; /* huh? */
1279  "Service `%s' will bind to `%s'\n",
1280  service_name,
1281  GNUNET_a2s(pos->ai_addr, pos->ai_addrlen));
1282  if (AF_INET == pos->ai_family)
1283  {
1284  GNUNET_assert(sizeof(struct sockaddr_in) == pos->ai_addrlen);
1285  saddrlens[i] = pos->ai_addrlen;
1286  saddrs[i] = GNUNET_malloc(saddrlens[i]);
1287  GNUNET_memcpy(saddrs[i], pos->ai_addr, saddrlens[i]);
1288  ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port);
1289  }
1290  else
1291  {
1292  GNUNET_assert(AF_INET6 == pos->ai_family);
1293  GNUNET_assert(sizeof(struct sockaddr_in6) == pos->ai_addrlen);
1294  saddrlens[i] = pos->ai_addrlen;
1295  saddrs[i] = GNUNET_malloc(saddrlens[i]);
1296  GNUNET_memcpy(saddrs[i], pos->ai_addr, saddrlens[i]);
1297  ((struct sockaddr_in6 *)saddrs[i])->sin6_port = htons(port);
1298  }
1299  i++;
1300  }
1301  GNUNET_free(hostname);
1302  freeaddrinfo(res);
1303  resi = i;
1304  }
1305  else
1306  {
1307  /* will bind against everything, just set port */
1308  if (disablev6)
1309  {
1310  /* V4-only */
1311  resi = 1;
1312  if (NULL != unixpath)
1313  resi++;
1314  i = 0;
1315  saddrs = GNUNET_malloc((resi + 1) * sizeof(struct sockaddr *));
1316  saddrlens = GNUNET_malloc((resi + 1) * sizeof(socklen_t));
1317  if (NULL != unixpath)
1318  {
1319  add_unixpath(saddrs, saddrlens, unixpath, abstract);
1320  i++;
1321  }
1322  saddrlens[i] = sizeof(struct sockaddr_in);
1323  saddrs[i] = GNUNET_malloc(saddrlens[i]);
1324 #if HAVE_SOCKADDR_IN_SIN_LEN
1325  ((struct sockaddr_in *)saddrs[i])->sin_len = saddrlens[i];
1326 #endif
1327  ((struct sockaddr_in *)saddrs[i])->sin_family = AF_INET;
1328  ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port);
1329  }
1330  else
1331  {
1332  /* dual stack */
1333  resi = 2;
1334  if (NULL != unixpath)
1335  resi++;
1336  saddrs = GNUNET_malloc((resi + 1) * sizeof(struct sockaddr *));
1337  saddrlens = GNUNET_malloc((resi + 1) * sizeof(socklen_t));
1338  i = 0;
1339  if (NULL != unixpath)
1340  {
1341  add_unixpath(saddrs, saddrlens, unixpath, abstract);
1342  i++;
1343  }
1344  saddrlens[i] = sizeof(struct sockaddr_in6);
1345  saddrs[i] = GNUNET_malloc(saddrlens[i]);
1346 #if HAVE_SOCKADDR_IN_SIN_LEN
1347  ((struct sockaddr_in6 *)saddrs[i])->sin6_len = saddrlens[0];
1348 #endif
1349  ((struct sockaddr_in6 *)saddrs[i])->sin6_family = AF_INET6;
1350  ((struct sockaddr_in6 *)saddrs[i])->sin6_port = htons(port);
1351  i++;
1352  saddrlens[i] = sizeof(struct sockaddr_in);
1353  saddrs[i] = GNUNET_malloc(saddrlens[i]);
1354 #if HAVE_SOCKADDR_IN_SIN_LEN
1355  ((struct sockaddr_in *)saddrs[i])->sin_len = saddrlens[1];
1356 #endif
1357  ((struct sockaddr_in *)saddrs[i])->sin_family = AF_INET;
1358  ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port);
1359  }
1360  }
1361  GNUNET_free_non_null(unixpath);
1362  *addrs = saddrs;
1363  *addr_lens = saddrlens;
1364  return resi;
1365 }
int GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
int GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:681
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
static int ret
Final status code.
Definition: gnunet-arm.c:89
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
int GNUNET_CONFIGURATION_have_value(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Test if we have a value for a particular option.
static char * service_name
Option -s: service name (hash to get service descriptor)
Definition: gnunet-vpn.c:51
const char * GNUNET_a2s(const struct sockaddr *addr, socklen_t addrlen)
Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string (for printing debug messages)...
static int res
int GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static char * hostname
Our hostname; we give this to all the peers we start.
static uint16_t port
Port number.
Definition: gnunet-bcd.c:81
int GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
handle to a socket
Definition: network.c:46
char * GNUNET_NETWORK_shorten_unixpath(char *unixpath)
Given a unixpath that is too long (larger than UNIX_PATH_MAX), shorten it to an acceptable length whi...
Definition: network.c:151
#define GNUNET_YES
Definition: gnunet_common.h:77
int GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
#define LOG(kind,...)
static void add_unixpath(struct sockaddr **saddrs, socklen_t *saddrlens, const char *unixpath, int abstract)
Add the given UNIX domain path as an address to the list (as the first entry).
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:548
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:900
Here is the call graph for this function:
Here is the caller graph for this function:

◆ notify_session_monitor()

static void notify_session_monitor ( struct Plugin plugin,
struct GNUNET_ATS_Session session,
enum GNUNET_TRANSPORT_SessionState  state 
)
static

If a session monitor is attached, notify it about the new session state.

Parameters
pluginour plugin
sessionsession that changed state
statenew state of the session

Definition at line 1378 of file plugin_transport_tcp.c.

References GNUNET_ATS_Session::address, GNUNET_TRANSPORT_SessionInfo::address, GNUNET_ATS_Session::bytes_in_queue, GNUNET_HELLO_address_check_option(), GNUNET_HELLO_ADDRESS_INFO_INBOUND, GNUNET_TRANSPORT_SessionInfo::is_inbound, GNUNET_ATS_Session::msgs_in_queue, GNUNET_TRANSPORT_SessionInfo::num_bytes_pending, GNUNET_TRANSPORT_SessionInfo::num_msg_pending, GNUNET_TRANSPORT_SessionInfo::receive_delay, GNUNET_ATS_Session::receive_delay, GNUNET_ATS_Session::receive_delay_task, GNUNET_TRANSPORT_SessionInfo::session_timeout, Plugin::sic, Plugin::sic_cls, state, GNUNET_TRANSPORT_SessionInfo::state, and GNUNET_ATS_Session::timeout.

Referenced by create_session(), do_transmit(), send_session_info_iter(), session_timeout(), tcp_plugin_disconnect_session(), and tcp_plugin_send().

1381 {
1382  struct GNUNET_TRANSPORT_SessionInfo info;
1383 
1384  if (NULL == plugin->sic)
1385  return;
1386  memset(&info, 0, sizeof(info));
1387  info.state = state;
1388  info.is_inbound =
1391  info.num_msg_pending = session->msgs_in_queue;
1392  info.num_bytes_pending = session->bytes_in_queue;
1393  if (NULL != session->receive_delay_task)
1394  info.receive_delay = session->receive_delay;
1395  info.session_timeout = session->timeout;
1396  info.address = session->address;
1397  plugin->sic(plugin->sic_cls, session, &info);
1398 }
GNUNET_TRANSPORT_SessionInfoCallback sic
Function to call about session status changes.
struct GNUNET_TIME_Absolute receive_delay
When will we continue to read from the socket? (used to enforce inbound quota).
unsigned int msgs_in_queue
Number of messages waiting for transmission to this peer.
struct GNUNET_SCHEDULER_Task * receive_delay_task
ID of task used to delay receiving more to throttle sender.
struct GNUNET_TIME_Absolute timeout
When does this session time out.
struct GNUNET_HELLO_Address * address
Address.
unsigned long long bytes_in_queue
Number of bytes waiting for transmission to this peer.
int GNUNET_HELLO_address_check_option(const struct GNUNET_HELLO_Address *address, enum GNUNET_HELLO_AddressInfo option)
Check if an address has a local option set.
Definition: address.c:39
Information about a plugin&#39;s session.
enum State state
current state of profiling
This is an inbound address and cannot be used to initiate an outbound connection to another peer...
void * sic_cls
Closure for sic.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tcp_nat_port_map_callback()

static void tcp_nat_port_map_callback ( void *  cls,
void **  app_ctx,
int  add_remove,
enum GNUNET_NAT_AddressClass  ac,
const struct sockaddr *  addr,
socklen_t  addrlen 
)
static

Our external IP address/port mapping has changed.

Parameters
clsclosure, the struct Plugin
app_ctx[in,out]location where the app can store stuff on add and retrieve it on remove
add_removeGNUNET_YES to mean the new public IP address, GNUNET_NO to mean the previous (now invalid) one
acaddress class the address belongs to
addreither the previous or the new public IP address
addrlenactual length of addr

Definition at line 1414 of file plugin_transport_tcp.c.

References address, find_typedefs::arg, gnunet-chk::args, GNUNET_DATACACHE_PluginEnvironment::cls, Plugin::env, GNUNET_a2s(), GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_INFO, GNUNET_HELLO_address_allocate(), GNUNET_HELLO_address_free, GNUNET_HELLO_ADDRESS_INFO_NONE, GNUNET_memcpy, GNUNET_YES, IPv4TcpAddress::ipv4_addr, IPv6TcpAddress::ipv6_addr, LOG, Plugin::myoptions, IPv4TcpAddress::options, IPv6TcpAddress::options, plugin, PLUGIN_NAME, t4, IPv4TcpAddress::t4_port, t6, and IPv6TcpAddress::t6_port.

Referenced by libgnunet_plugin_transport_tcp_init().

1420 {
1421  struct Plugin *plugin = cls;
1422  struct GNUNET_HELLO_Address *address;
1423  struct IPv4TcpAddress t4;
1424  struct IPv6TcpAddress t6;
1425  void *arg;
1426  size_t args;
1427 
1428  (void)app_ctx;
1430  "NAT notification to %s address `%s'\n",
1431  (GNUNET_YES == add_remove) ? "add" : "remove",
1432  GNUNET_a2s(addr, addrlen));
1433  /* convert 'addr' to our internal format */
1434  switch (addr->sa_family)
1435  {
1436  case AF_INET:
1437  GNUNET_assert(addrlen == sizeof(struct sockaddr_in));
1438  memset(&t4, 0, sizeof(t4));
1439  t4.options = htonl(plugin->myoptions);
1440  t4.ipv4_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
1441  t4.t4_port = ((struct sockaddr_in *)addr)->sin_port;
1442  arg = &t4;
1443  args = sizeof(t4);
1444  break;
1445 
1446  case AF_INET6:
1447  if (IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)addr)->sin6_addr))
1448  {
1449  /* skip link local, we don't allow them in
1450  #tcp_plugin_check_address() */
1451  return;
1452  }
1453  GNUNET_assert(addrlen == sizeof(struct sockaddr_in6));
1454  memset(&t6, 0, sizeof(t6));
1455  GNUNET_memcpy(&t6.ipv6_addr,
1456  &((struct sockaddr_in6 *)addr)->sin6_addr,
1457  sizeof(struct in6_addr));
1458  t6.options = htonl(plugin->myoptions);
1459  t6.t6_port = ((struct sockaddr_in6 *)addr)->sin6_port;
1460  arg = &t6;
1461  args = sizeof(t6);
1462  break;
1463 
1464  default:
1465  GNUNET_break(0);
1466  return;
1467  }
1468  /* modify our published address list */
1469  GNUNET_assert((args == sizeof(struct IPv4TcpAddress)) ||
1470  (args == sizeof(struct IPv6TcpAddress)));
1471  /* TODO: use 'ac' here in the future... */
1472  address = GNUNET_HELLO_address_allocate(plugin->env->my_identity,
1473  PLUGIN_NAME,
1474  arg,
1475  args,
1477  plugin->env->notify_address(plugin->env->cls, add_remove, address);
1478  GNUNET_HELLO_address_free(address);
1479 }
struct GNUNET_HELLO_Address * GNUNET_HELLO_address_allocate(const struct GNUNET_PeerIdentity *peer, const char *transport_name, const void *address, size_t address_length, enum GNUNET_HELLO_AddressInfo local_info)
Allocate an address struct.
Definition: address.c:73
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
Network format for IPv4 addresses.
struct GNUNET_DATACACHE_PluginEnvironment * env
Our execution environment.
static struct GNUNET_SCHEDULER_Task * t4
Task for IPv4 socket.
const char * GNUNET_a2s(const struct sockaddr *addr, socklen_t addrlen)
Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string (for printing debug messages)...
Network format for IPv6 addresses.
#define PLUGIN_NAME
No additional information.
Handle for a plugin.
Definition: block.c:37
An address for communicating with a peer.
void * cls
Closure to use for callbacks.
#define GNUNET_YES
Definition: gnunet_common.h:77
uint32_t myoptions
Address options.
#define LOG(kind,...)
static char * address
GNS address for this phone.
#define GNUNET_HELLO_address_free(addr)
Free an address.
static struct GNUNET_SCHEDULER_Task * t6
Task for IPv6 socket.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tcp_plugin_address_to_string()

static const char* tcp_plugin_address_to_string ( void *  cls,
const void *  addr,
size_t  addrlen 
)
static

Function called for a quick conversion of the binary address to a numeric address.

Note that the caller must not free the address and that the next call to this function is allowed to override the address again.

Parameters
clsclosure (struct Plugin*)
addrbinary address
addrlenlength of addr
Returns
string representing the same address

Definition at line 1494 of file plugin_transport_tcp.c.

References buf, GNUNET_ERROR_TYPE_WARNING, GNUNET_log_strerror, GNUNET_memcpy, GNUNET_snprintf(), IPv6TcpAddress::ipv6_addr, LOG, options, PLUGIN_NAME, port, t4, t6, and IPv6TcpAddress::t6_port.

Referenced by create_session(), disconnect_notify(), do_transmit(), handle_tcp_welcome(), libgnunet_plugin_transport_tcp_init(), nat_connect_timeout(), tcp_plugin_disconnect_session(), and tcp_plugin_get_session().

1495 {
1496  static char rbuf[INET6_ADDRSTRLEN + 12];
1497  char buf[INET6_ADDRSTRLEN];
1498  const void *sb;
1499  struct in_addr a4;
1500  struct in6_addr a6;
1501  const struct IPv4TcpAddress *t4;
1502  const struct IPv6TcpAddress *t6;
1503  int af;
1504  uint16_t port;
1505  uint32_t options;
1506 
1507  switch (addrlen)
1508  {
1509  case sizeof(struct IPv6TcpAddress):
1510  t6 = addr;
1511  af = AF_INET6;
1512  port = ntohs(t6->t6_port);
1513  options = ntohl(t6->options);
1514  GNUNET_memcpy(&a6, &t6->ipv6_addr, sizeof(a6));
1515  sb = &a6;
1516  break;
1517 
1518  case sizeof(struct IPv4TcpAddress):
1519  t4 = addr;
1520  af = AF_INET;
1521  port = ntohs(t4->t4_port);
1522  options = ntohl(t4->options);
1523  GNUNET_memcpy(&a4, &t4->ipv4_addr, sizeof(a4));
1524  sb = &a4;
1525  break;
1526 
1527  default:
1528  LOG(GNUNET_ERROR_TYPE_WARNING,
1529  _("Unexpected address length: %u bytes\n"),
1530  (unsigned int)addrlen);
1531  return NULL;
1532  }
1533  if (NULL == inet_ntop(af, sb, buf, INET6_ADDRSTRLEN))
1534  {
1536  return NULL;
1537  }
1538  GNUNET_snprintf(rbuf,
1539  sizeof(rbuf),
1540  (af == AF_INET6) ? "%s.%u.[%s]:%u" : "%s.%u.%s:%u",
1541  PLUGIN_NAME,
1542  options,
1543  buf,
1544  port);
1545  return rbuf;
1546 }
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
int GNUNET_snprintf(char *buf, size_t size, const char *format,...)
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
Network format for IPv4 addresses.
static struct GNUNET_SCHEDULER_Task * t4
Task for IPv4 socket.
static char buf[2048]
Network format for IPv6 addresses.
struct in6_addr ipv6_addr
IPv6 address.
#define PLUGIN_NAME
static uint16_t port
Port number.
Definition: gnunet-bcd.c:81
#define LOG(kind,...)
uint16_t t6_port
Port number, in network byte order.
static struct GNUNET_SCHEDULER_Task * t6
Task for IPv6 socket.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tcp_plugin_string_to_address()

static int tcp_plugin_string_to_address ( void *  cls,
const char *  addr,
uint16_t  addrlen,
void **  buf,
size_t *  added 
)
static

Function called to convert a string address to a binary address.

Parameters
clsclosure (struct Plugin*)
addrstring address
addrlenlength of the address
buflocation to store the buffer
addedlocation to store the number of bytes in the buffer. If the function returns GNUNET_SYSERR, its contents are undefined.
Returns
GNUNET_OK on success, GNUNET_SYSERR on failure

Definition at line 1562 of file plugin_transport_tcp.c.

References address, GNUNET_break, GNUNET_free, GNUNET_new, GNUNET_OK, GNUNET_strdup, GNUNET_STRINGS_to_address_ip(), GNUNET_SYSERR, IPv4TcpAddress::ipv4_addr, IPv6TcpAddress::ipv6_addr, options, IPv4TcpAddress::options, IPv6TcpAddress::options, plugin, t4, IPv4TcpAddress::t4_port, t6, and IPv6TcpAddress::t6_port.

Referenced by libgnunet_plugin_transport_tcp_init().

1567 {
1568  struct sockaddr_storage socket_address;
1569  char *address;
1570  char *plugin;
1571  char *optionstr;
1572  uint32_t options;
1573 
1574  /* Format tcp.options.address:port */
1575  address = NULL;
1576  plugin = NULL;
1577  optionstr = NULL;
1578  if ((NULL == addr) || (0 == addrlen))
1579  {
1580  GNUNET_break(0);
1581  return GNUNET_SYSERR;
1582  }
1583  if ('\0' != addr[addrlen - 1])
1584  {
1585  GNUNET_break(0);
1586  return GNUNET_SYSERR;
1587  }
1588  if (strlen(addr) != addrlen - 1)
1589  {
1590  GNUNET_break(0);
1591  return GNUNET_SYSERR;
1592  }
1593  plugin = GNUNET_strdup(addr);
1594  optionstr = strchr(plugin, '.');
1595  if (NULL == optionstr)
1596  {
1597  GNUNET_break(0);
1598  GNUNET_free(plugin);
1599  return GNUNET_SYSERR;
1600  }
1601  optionstr[0] = '\0';
1602  optionstr++;
1603  options = atol(optionstr);
1604  address = strchr(optionstr, '.');
1605  if (NULL == address)
1606  {
1607  GNUNET_break(0);
1608  GNUNET_free(plugin);
1609  return GNUNET_SYSERR;
1610  }
1611  address[0] = '\0';
1612  address++;
1613 
1614  if (GNUNET_OK !=
1615  GNUNET_STRINGS_to_address_ip(address, strlen(address), &socket_address))
1616  {
1617  GNUNET_break(0);
1618  GNUNET_free(plugin);
1619  return GNUNET_SYSERR;
1620  }
1621 
1622  GNUNET_free(plugin);
1623  switch (socket_address.ss_family)
1624  {
1625  case AF_INET: {
1626  struct IPv4TcpAddress *t4;
1627  struct sockaddr_in *in4 = (struct sockaddr_in *)&socket_address;
1628  t4 = GNUNET_new(struct IPv4TcpAddress);
1629  t4->options = htonl(options);
1630  t4->ipv4_addr = in4->sin_addr.s_addr;
1631  t4->t4_port = in4->sin_port;
1632  *buf = t4;
1633  *added = sizeof(struct IPv4TcpAddress);
1634  return GNUNET_OK;
1635  }
1636 
1637  case AF_INET6: {
1638  struct IPv6TcpAddress *t6;
1639  struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)&socket_address;
1640  t6 = GNUNET_new(struct IPv6TcpAddress);
1641  t6->options = htonl(options);
1642  t6->ipv6_addr = in6->sin6_addr;
1643  t6->t6_port = in6->sin6_port;
1644  *buf = t6;
1645  *added = sizeof(struct IPv6TcpAddress);
1646  return GNUNET_OK;
1647  }
1648 
1649  default:
1650  return GNUNET_SYSERR;
1651  }
1652 }
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
#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.
uint32_t options
Optional flags for this address see enum TcpAddressOptions
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
Network format for IPv4 addresses.
uint32_t options
Optional options and flags for this address, see enum TcpAddressOptions
static struct GNUNET_SCHEDULER_Task * t4
Task for IPv4 socket.
static char buf[2048]
Network format for IPv6 addresses.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
struct in6_addr ipv6_addr
IPv6 address.
uint16_t t4_port
Port number, in network byte order.
uint32_t ipv4_addr
IPv4 address, in network byte order.
static char * address
GNS address for this phone.
int GNUNET_STRINGS_to_address_ip(const char *addr, uint16_t addrlen, struct sockaddr_storage *r_buf)
Tries to convert addr string to an IP (v4 or v6) address.
Definition: strings.c:1327
uint16_t t6_port
Port number, in network byte order.
#define GNUNET_free(ptr)
Wrapper around free.
static struct GNUNET_SCHEDULER_Task * t6
Task for IPv6 socket.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ lookup_session_by_client()

static struct GNUNET_ATS_Session* lookup_session_by_client ( struct Plugin plugin,
struct GNUNET_SERVER_Client client 
)
static

Find the session handle for the given client.

Currently uses both the hashmap and the client context, as the client context is new and the logic still needs to be tested.

Parameters
pluginthe plugin
clientwhich client to find the session handle for
Returns
NULL if no matching session exists

Definition at line 1666 of file plugin_transport_tcp.c.

References GNUNET_SERVER_client_get_user_context.

Referenced by disconnect_notify(), handle_tcp_data(), and handle_tcp_welcome().

1668 {
1670  struct GNUNET_ATS_Session);
1671 }
#define GNUNET_SERVER_client_get_user_context(client, type)
Return user context associated with the given client.
Information about ongoing sessions of the transport client.
Here is the caller graph for this function:

◆ tcp_plugin_disconnect_session()

static int tcp_plugin_disconnect_session ( void *  cls,
struct GNUNET_ATS_Session session 
)
static

Functions with this signature are called whenever we need to close a session due to a disconnect or failure to establish a connection.

Parameters
clsthe struct Plugin
sessionsession to close down
Returns
GNUNET_OK on success

Definition at line 1684 of file plugin_transport_tcp.c.

References GNUNET_HELLO_Address::address, GNUNET_ATS_Session::address, GNUNET_HELLO_Address::address_length, GNUNET_ATS_Session::bytes_in_queue, GNUNET_ATS_Session::client, GNUNET_DATACACHE_PluginEnvironment::cls, Plugin::env, gettext_noop, GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multipeermap_remove(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_HELLO_address_free, GNUNET_i2s(), GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_cancel(), GNUNET_SERVER_client_disconnect(), GNUNET_SERVER_client_set_user_context, GNUNET_SERVER_notify_transmit_ready_cancel(), GNUNET_STATISTICS_update(), GNUNET_SYSERR, GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_SS_DONE, GNUNET_YES, LOG, PendingMessage::message_size, GNUNET_ATS_Session::msgs_in_queue, GNUNET_ATS_Session::nat_connection_timeout, Plugin::nat_wait_conns, notify_session_monitor(), GNUNET_ATS_Session::pending_messages_head, GNUNET_ATS_Session::pending_messages_tail, plugin, GNUNET_ATS_Session::plugin, pm, GNUNET_ATS_Session::receive_delay_task, Plugin::sessionmap, GNUNET_ATS_Session::target, tcp_plugin_address_to_string(), GNUNET_ATS_Session::timeout, GNUNET_ATS_Session::timeout_task, PendingMessage::transmit_cont, PendingMessage::transmit_cont_cls, and GNUNET_ATS_Session::transmit_handle.

Referenced by disconnect_notify(), handle_tcp_nat_probe(), libgnunet_plugin_transport_tcp_init(), nat_connect_timeout(), session_disconnect_it(), session_timeout(), and tcp_plugin_get_session().

1685 {
1686  struct Plugin *plugin = cls;
1687  struct PendingMessage *pm;
1688 
1690  "Disconnecting session of peer `%s' address `%s'\n",
1691  GNUNET_i2s(&session->target),
1693  session->address->address,
1694  session->address->address_length));
1695 
1696  if (NULL != session->timeout_task)
1697  {
1699  session->timeout_task = NULL;
1701  }
1702 
1704  &session->target,
1705  session))
1706  {
1707  GNUNET_STATISTICS_update(session->plugin->env->stats,
1708  gettext_noop("# TCP sessions active"),
1709  -1,
1710  GNUNET_NO);
1711  }
1712  else
1713  {
1716  &session->target,
1717  session));
1718  }
1719  if (NULL != session->client)
1721 
1722  /* clean up state */
1723  if (NULL != session->transmit_handle)
1724  {
1726  session->transmit_handle = NULL;
1727  }
1728  session->plugin->env->session_end(session->plugin->env->cls,
1729  session->address,
1730  session);
1731 
1732  if (NULL != session->nat_connection_timeout)
1733  {
1735  session->nat_connection_timeout = NULL;
1736  }
1737 
1738  while (NULL != (pm = session->pending_messages_head))
1739  {
1741  (NULL != pm->transmit_cont)
1742  ? "Could not deliver message to `%s' at %s.\n"
1743  : "Could not deliver message to `%s' at %s, notifying.\n",
1744  GNUNET_i2s(&session->target),
1746  session->address->address,
1747  session->address->address_length));
1748  GNUNET_STATISTICS_update(session->plugin->env->stats,
1749  gettext_noop("# bytes currently in TCP buffers"),
1750  -(int64_t)pm->message_size,
1751  GNUNET_NO);
1752  GNUNET_STATISTICS_update(session->plugin->env->stats,
1753  gettext_noop(
1754  "# bytes discarded by TCP (disconnect)"),
1755  pm->message_size,
1756  GNUNET_NO);
1758  session->pending_messages_tail,
1759  pm);
1760  GNUNET_assert(0 < session->msgs_in_queue);
1761  session->msgs_in_queue--;
1762  GNUNET_assert(pm->message_size <= session->bytes_in_queue);
1763  session->bytes_in_queue -= pm->message_size;
1764  if (NULL != pm->transmit_cont)
1766  &session->target,
1767  GNUNET_SYSERR,
1768  pm->message_size,
1769  0);
1770  GNUNET_free(pm);
1771  }
1772  GNUNET_assert(0 == session->msgs_in_queue);
1773  GNUNET_assert(0 == session->bytes_in_queue);
1775 
1776  if (NULL != session->receive_delay_task)
1777  {
1779  session->receive_delay_task = NULL;
1780  }
1781  if (NULL != session->client)
1782  {
1784  session->client = NULL;
1785  }
1787  GNUNET_assert(NULL == session->transmit_handle);
1788  GNUNET_free(session);
1789  return GNUNET_OK;
1790 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
size_t address_length
Number of bytes in address.
size_t message_size
So that the gnunet-service-transport can group messages together, these pending messages need to acce...
Session is being torn down and about to disappear.
struct GNUNET_CONTAINER_MultiPeerMap * sessionmap
Map from peer identities to sessions for the given peer.
GNUNET_TRANSPORT_TransmitContinuation transmit_cont
Continuation function to call once the message has been sent.
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
const void * address
Binary representation of the address (plugin-specific).
void * transmit_cont_cls
Closure for transmit_cont.
unsigned int msgs_in_queue
Number of messages waiting for transmission to this peer.
struct GNUNET_SCHEDULER_Task * timeout_task
Session timeout task.
struct Plugin * plugin
Pointer to the global plugin struct.
struct GNUNET_SERVER_TransmitHandle * transmit_handle
Handle for pending transmission request.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_SCHEDULER_Task * nat_connection_timeout
Task cleaning up a NAT client connection establishment attempt;.
struct GNUNET_SCHEDULER_Task * receive_delay_task
ID of task used to delay receiving more to throttle sender.
struct GNUNET_TIME_Absolute timeout
When does this session time out.
int GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
void GNUNET_SERVER_notify_transmit_ready_cancel(struct GNUNET_SERVER_TransmitHandle *th)
Abort transmission request.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
struct GNUNET_HELLO_Address * address
Address.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
unsigned long long bytes_in_queue
Number of bytes waiting for transmission to this peer.
void GNUNET_SERVER_client_disconnect(struct GNUNET_SERVER_Client *client)
Ask the server to disconnect from the given client.
static void notify_session_monitor(struct Plugin *plugin, struct GNUNET_ATS_Session *session, enum GNUNET_TRANSPORT_SessionState state)
If a session monitor is attached, notify it about the new session state.
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
struct PendingMessage * pending_messages_tail
Messages currently pending for transmission to this peer, if any.
struct GNUNET_DATACACHE_PluginEnvironment * env
Our execution environment.
struct PendingMessage * pending_messages_head
Messages currently pending for transmission to this peer, if any.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static const char * tcp_plugin_address_to_string(void *cls, const void *addr, size_t addrlen)
Function called for a quick conversion of the binary address to a numeric address.
#define GNUNET_SERVER_client_set_user_context(client, value)
Set user context to be associated with the given client.
Handle for a plugin.
Definition: block.c:37
struct GNUNET_PeerIdentity target
To whom are we talking to.
List containing all messages that are yet to be send.
struct Client * client
The transport client that provided the session.
void * cls
Closure to use for callbacks.
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_CONTAINER_MultiPeerMap * nat_wait_conns
Map of peers we have tried to contact behind a NAT.
#define LOG(kind,...)
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_HELLO_address_free(addr)
Free an address.
#define GNUNET_free(ptr)
Wrapper around free.
static struct GNUNET_TRANSPORT_PluginMonitor * pm
Handle if we are monitoring plugin session activity.
#define gettext_noop(String)
Definition: gettext.h:69
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tcp_plugin_query_keepalive_factor()

static unsigned int tcp_plugin_query_keepalive_factor ( void *  cls)
static

Function that is called to get the keepalive factor.

GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT is divided by this number to calculate the interval between keepalive packets.

Parameters
clsclosure with the struct Plugin
Returns
keepalive factor

Definition at line 1802 of file plugin_transport_tcp.c.

Referenced by libgnunet_plugin_transport_tcp_init().

1803 {
1804  return 3;
1805 }
Here is the caller graph for this function:

◆ session_timeout()

static void session_timeout ( void *  cls)
static

Session was idle for too long, so disconnect it.

Parameters
clsthe struct GNUNET_ATS_Session of the idle session

Definition at line 1814 of file plugin_transport_tcp.c.

References GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, GNUNET_ERROR_TYPE_DEBUG, GNUNET_SCHEDULER_add_delayed(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_absolute_get_remaining(), GNUNET_TRANSPORT_SS_UPDATE, GNUNET_YES, LOG, notify_session_monitor(), GNUNET_ATS_Session::plugin, GNUNET_TIME_Relative::rel_value_us, tcp_plugin_disconnect_session(), GNUNET_ATS_Session::timeout, and GNUNET_ATS_Session::timeout_task.

Referenced by create_session().

1815 {
1816  struct GNUNET_ATS_Session *s = cls;
1817  struct GNUNET_TIME_Relative left;
1818 
1819  s->timeout_task = NULL;
1821  if (0 != left.rel_value_us)
1822  {
1823  /* not actually our turn yet, but let's at least update
1824  the monitor, it may think we're about to die ... */
1827  return;
1828  }
1830  "Session %p was idle for %s, disconnecting\n",
1831  s,
1834  GNUNET_YES));
1835  /* call session destroy function */
1837 }
struct GNUNET_SCHEDULER_Task * timeout_task
Session timeout task.
struct Plugin * plugin
Pointer to the global plugin struct.
struct GNUNET_TIME_Absolute timeout
When does this session time out.
static void notify_session_monitor(struct Plugin *plugin, struct GNUNET_ATS_Session *session, enum GNUNET_TRANSPORT_SessionState state)
If a session monitor is attached, notify it about the new session state.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1237
static int tcp_plugin_disconnect_session(void *cls, struct GNUNET_ATS_Session *session)
Functions with this signature are called whenever we need to close a session due to a disconnect or f...
Information about ongoing sessions of the transport client.
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:686
#define GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT
After how long do we consider a connection to a peer dead if we don&#39;t receive messages from the peer...
This is just an update about the session, the state did not change.
static void session_timeout(void *cls)
Session was idle for too long, so disconnect it.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
#define GNUNET_YES
Definition: gnunet_common.h:77
#define LOG(kind,...)
Time for relative time used by GNUnet, in microseconds.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ reschedule_session_timeout()

static void reschedule_session_timeout ( struct GNUNET_ATS_Session s)
static

Increment session timeout due to activity.

Parameters
ssession to increment timeout for

Definition at line 1846 of file plugin_transport_tcp.c.

References GNUNET_assert, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, GNUNET_TIME_relative_to_absolute(), GNUNET_ATS_Session::timeout, and GNUNET_ATS_Session::timeout_task.

Referenced by delayed_done(), handle_tcp_data(), and tcp_plugin_update_session_timeout().

1847 {
1848  GNUNET_assert(NULL != s->timeout_task);
1849  s->timeout =
1851 }
struct GNUNET_SCHEDULER_Task * timeout_task
Session timeout task.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:246
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_TIME_Absolute timeout
When does this session time out.
#define GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT
After how long do we consider a connection to a peer dead if we don&#39;t receive messages from the peer...
Here is the call graph for this function:
Here is the caller graph for this function:

◆ create_session()

static struct GNUNET_ATS_Session* create_session ( struct Plugin plugin,
const struct GNUNET_HELLO_Address address,
enum GNUNET_NetworkType  scope,
struct GNUNET_SERVER_Client client,
int  is_nat 
)
static

Create a new session.

Also queues a welcome message.

Parameters
pluginthe plugin
addressthe address to create the session for
scopenetwork scope the address is from
clientclient to use, reference counter must have already been increased
is_natthis a NAT session, we should wait for a client to connect to us from an address, then assign that to the session
Returns
new session object

Definition at line 1867 of file plugin_transport_tcp.c.

References GNUNET_HELLO_Address::address, GNUNET_ATS_Session::address, GNUNET_HELLO_Address::address_length, GNUNET_ATS_Session::bytes_in_queue, GNUNET_ATS_Session::client, PendingMessage::client, Plugin::env, GNUNET_ATS_Session::expecting_welcome, gettext_noop, GNUNET_assert, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_HELLO_address_copy(), GNUNET_i2s(), GNUNET_malloc, GNUNET_memcpy, GNUNET_new, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_SERVER_client_set_user_context, GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_get(), GNUNET_TIME_relative_to_absolute(), GNUNET_TIME_UNIT_FOREVER_ABS, GNUNET_TRANSPORT_SS_HANDSHAKE, GNUNET_TRANSPORT_SS_INIT, GNUNET_TRANSPORT_SS_UP, GNUNET_YES, GNUNET_ATS_Session::is_nat, GNUNET_ATS_Session::last_activity, LOG, PendingMessage::message_size, PendingMessage::msg, GNUNET_ATS_Session::msgs_in_queue, Plugin::my_welcome, notify_session_monitor(), GNUNET_HELLO_Address::peer, GNUNET_ATS_Session::pending_messages_head, GNUNET_ATS_Session::pending_messages_tail, plugin, GNUNET_ATS_Session::plugin, pm, process_pending_messages(), scope, GNUNET_ATS_Session::scope, session_timeout(), GNUNET_ATS_Session::target, tcp_plugin_address_to_string(), GNUNET_ATS_Session::timeout, PendingMessage::timeout, and GNUNET_ATS_Session::timeout_task.

Referenced by handle_tcp_welcome(), and tcp_plugin_get_session().

1872 {
1873  struct GNUNET_ATS_Session *session;
1874  struct PendingMessage *pm;
1875 
1876  if (GNUNET_YES != is_nat)
1877  GNUNET_assert(NULL != client);
1878  else
1879  GNUNET_assert(NULL == client);
1880 
1882  "Creating new session for peer `%s' at address %s\n",
1883  GNUNET_i2s(&address->peer),
1885  address->address,
1886  address->address_length));
1887  session = GNUNET_new(struct GNUNET_ATS_Session);
1889  session->plugin = plugin;
1890  session->is_nat = is_nat;
1891  if (NULL != client)
1892  {
1893  session->client = client;
1894  GNUNET_SERVER_client_set_user_context(client, session);
1895  }
1896  session->address = GNUNET_HELLO_address_copy(address);
1897  session->target = address->peer;
1898  session->expecting_welcome = GNUNET_YES;
1899  session->scope = scope;
1900  pm = GNUNET_malloc(sizeof(struct PendingMessage) +
1901  sizeof(struct WelcomeMessage));
1902  pm->msg = (const char *)&pm[1];
1903  pm->message_size = sizeof(struct WelcomeMessage);
1904  GNUNET_memcpy(&pm[1], &plugin->my_welcome, sizeof(struct WelcomeMessage));
1906  GNUNET_STATISTICS_update(plugin->env->stats,
1907  gettext_noop("# bytes currently in TCP buffers"),
1908  pm->message_size,
1909  GNUNET_NO);
1911  session->pending_messages_tail,
1912  pm);
1913  session->msgs_in_queue++;
1914  session->bytes_in_queue += pm->message_size;
1915  session->timeout =
1917  session->timeout_task =
1919  &session_timeout,
1920  session);
1922  if (GNUNET_YES != is_nat)
1923  {
1924  GNUNET_STATISTICS_update(plugin->env->stats,
1925  gettext_noop("# TCP sessions active"),
1926  1,
1927  GNUNET_NO);
1929  }
1930  else
1931  {
1932  notify_session_monitor(session->plugin,
1933  session,
1935  }
1936  return session;
1937 }
size_t address_length
Number of bytes in address.
size_t message_size
So that the gnunet-service-transport can group messages together, these pending messages need to acce...
const void * address
Binary representation of the address (plugin-specific).
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
unsigned int msgs_in_queue
Number of messages waiting for transmission to this peer.
struct GNUNET_SCHEDULER_Task * timeout_task
Session timeout task.
struct Plugin * plugin
Pointer to the global plugin struct.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:246
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
int is_nat
Was this session created using NAT traversal?
Initial session handshake is in progress.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct GNUNET_TIME_Absolute timeout
When does this session time out.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_HELLO_Address * address
Address.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
unsigned long long bytes_in_queue
Number of bytes waiting for transmission to this peer.
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
static void notify_session_monitor(struct Plugin *plugin, struct GNUNET_ATS_Session *session, enum GNUNET_TRANSPORT_SessionState state)
If a session monitor is attached, notify it about the new session state.
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
struct PendingMessage * pending_messages_tail
Messages currently pending for transmission to this peer, if any.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1237
Information about ongoing sessions of the transport client.
struct GNUNET_DATACACHE_PluginEnvironment * env
Our execution environment.
static enum GNUNET_NetworkType scope
Which network scope do we belong to?
struct PendingMessage * pending_messages_head
Messages currently pending for transmission to this peer, if any.
struct TransportClient * client
Client that issued the transmission request, if pmt is PMT_CORE.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
struct GNUNET_TIME_Absolute timeout
At what time should we give up on the transmission (and no longer retry)?
static const char * tcp_plugin_address_to_string(void *cls, const void *addr, size_t addrlen)
Function called for a quick conversion of the binary address to a numeric address.
enum GNUNET_NetworkType scope
ATS network type.
struct GNUNET_PeerIdentity peer
For which peer is this an address?
int expecting_welcome
Are we still expecting the welcome message? (GNUNET_YES/GNUNET_NO)
#define GNUNET_SERVER_client_set_user_context(client, value)
Set user context to be associated with the given client.
#define GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT
After how long do we consider a connection to a peer dead if we don&#39;t receive messages from the peer...
static void session_timeout(void *cls)
Session was idle for too long, so disconnect it.
struct GNUNET_PeerIdentity target
To whom are we talking to.
Initial handshake message for a session.
struct WelcomeMessage my_welcome
Welcome message used by this peer.
struct GNUNET_HELLO_Address * GNUNET_HELLO_address_copy(const struct GNUNET_HELLO_Address *address)
Copy an address struct.
Definition: address.c:109
The session was created (first call for each session object).
List containing all messages that are yet to be send.
const char * msg
The pending message.
struct Client * client
The transport client that provided the session.
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_TIME_Absolute last_activity
Last activity on this connection.
#define LOG(kind,...)
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_malloc(size)
Wrapper around malloc.
static struct GNUNET_TRANSPORT_PluginMonitor * pm
Handle if we are monitoring plugin session activity.
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_pending_messages()

static void process_pending_messages ( struct GNUNET_ATS_Session session)
static

If we have pending messages, ask the server to transmit them (schedule the respective tasks, etc.)

Parameters
sessionfor which session should we do this

Definition at line 2109 of file plugin_transport_tcp.c.

References GNUNET_ATS_Session::client, do_transmit(), GNUNET_assert, GNUNET_SERVER_notify_transmit_ready(), GNUNET_TIME_absolute_get_remaining(), PendingMessage::message_size, GNUNET_ATS_Session::pending_messages_head, pm, PendingMessage::timeout, and GNUNET_ATS_Session::transmit_handle.

Referenced by create_session(), do_transmit(), handle_tcp_nat_probe(), handle_tcp_welcome(), tcp_plugin_get_session(), and tcp_plugin_send().

2110 {
2111  struct PendingMessage *pm;
2112 
2113  GNUNET_assert(NULL != session->client);
2114  if (NULL != session->transmit_handle)
2115  return;
2116  if (NULL == (pm = session->pending_messages_head))
2117  return;
2118 
2119  session->transmit_handle =
2121  pm->message_size,
2123  pm->timeout),
2124  &do_transmit,
2125  session);
2126 }
size_t message_size
So that the gnunet-service-transport can group messages together, these pending messages need to acce...
struct GNUNET_SERVER_TransmitHandle * transmit_handle
Handle for pending transmission request.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static size_t do_transmit(void *cls, size_t size, void *buf)
Function called to notify a client about the socket being ready to queue more data.
struct PendingMessage * pending_messages_head
Messages currently pending for transmission to this peer, if any.
struct GNUNET_TIME_Absolute timeout
At what time should we give up on the transmission (and no longer retry)?
struct GNUNET_SERVER_TransmitHandle * GNUNET_SERVER_notify_transmit_ready(struct GNUNET_SERVER_Client *client, size_t size, struct GNUNET_TIME_Relative timeout, GNUNET_CONNECTION_TransmitReadyNotify callback, void *callback_cls)
Notify us when the server has enough space to transmit a message of the given size to the given clien...
List containing all messages that are yet to be send.
struct Client * client
The transport client that provided the session.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
static struct GNUNET_TRANSPORT_PluginMonitor * pm
Handle if we are monitoring plugin session activity.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_transmit()

static size_t do_transmit ( void *  cls,
size_t  size,
void *  buf 
)
static

Function called to notify a client about the socket being ready to queue more data.

"buf" will be NULL and "size" zero if the socket was closed for writing in the meantime.

Parameters
clsclosure
sizenumber of bytes available in buf
bufwhere the callee should write the message
Returns
number of bytes written to buf

Definition at line 1962 of file plugin_transport_tcp.c.

References GNUNET_TIME_Absolute::abs_value_us, GNUNET_HELLO_Address::address, GNUNET_ATS_Session::address, GNUNET_HELLO_Address::address_length, buf, GNUNET_ATS_Session::bytes_in_queue, Plugin::env, gettext_noop, GNUNET_assert, GNUNET_CONTAINER_DLL_insert_after, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_i2s(), GNUNET_memcpy, GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_SYSERR, GNUNET_TIME_absolute_get(), GNUNET_TRANSPORT_SS_UPDATE, GNUNET_ATS_Session::last_activity, LOG, PendingMessage::message_size, PendingMessage::msg, GNUNET_ATS_Session::msgs_in_queue, notify_session_monitor(), GNUNET_ATS_Session::pending_messages_head, GNUNET_ATS_Session::pending_messages_tail, plugin, GNUNET_ATS_Session::plugin, process_pending_messages(), ret, GNUNET_ATS_Session::target, tcp_plugin_address_to_string(), PendingMessage::timeout, PendingMessage::transmit_cont, PendingMessage::transmit_cont_cls, and GNUNET_ATS_Session::transmit_handle.

Referenced by process_pending_messages().

1963 {
1964  struct GNUNET_ATS_Session *session = cls;
1965  struct GNUNET_PeerIdentity pid;
1966  struct Plugin *plugin;
1967  struct PendingMessage *pos;
1968  struct PendingMessage *hd;
1969  struct PendingMessage *tl;
1970  struct GNUNET_TIME_Absolute now;
1971  char *cbuf;
1972  size_t ret;
1973 
1974  session->transmit_handle = NULL;
1975  plugin = session->plugin;
1976  if (NULL == buf)
1977  {
1979  "Timeout trying to transmit to peer `%s', discarding message queue.\n",
1980  GNUNET_i2s(&session->target));
1981  /* timeout; cancel all messages that have already expired */
1982  hd = NULL;
1983  tl = NULL;
1984  ret = 0;
1985  now = GNUNET_TIME_absolute_get();
1986  while ((NULL != (pos = session->pending_messages_head)) &&
1987  (pos->timeout.abs_value_us <= now.abs_value_us))
1988  {
1990  session->pending_messages_tail,
1991  pos);
1992  GNUNET_assert(0 < session->msgs_in_queue);
1993  session->msgs_in_queue--;
1994  GNUNET_assert(pos->message_size <= session->bytes_in_queue);
1995  session->bytes_in_queue -= pos->message_size;
1997  "Failed to transmit %u byte message to `%s'.\n",
1998  pos->message_size,
1999  GNUNET_i2s(&session->target));
2000  ret += pos->message_size;
2001  GNUNET_CONTAINER_DLL_insert_after(hd, tl, tl, pos);
2002  }
2003  /* do this call before callbacks (so that if callbacks destroy
2004  * session, they have a chance to cancel actions done by this
2005  * call) */
2006  process_pending_messages(session);
2007  pid = session->target;
2008  /* no do callbacks and do not use session again since
2009  * the callbacks may abort the session */
2010  while (NULL != (pos = hd))
2011  {
2012  GNUNET_CONTAINER_DLL_remove(hd, tl, pos);
2013  if (NULL != pos->transmit_cont)
2014  pos->transmit_cont(pos->transmit_cont_cls,
2015  &pid,
2016  GNUNET_SYSERR,
2017  pos->message_size,
2018  0);
2019  GNUNET_free(pos);
2020  }
2021  GNUNET_STATISTICS_update(plugin->env->stats,
2022  gettext_noop("# bytes currently in TCP buffers"),
2023  -(int64_t)ret,
2024  GNUNET_NO);
2025  GNUNET_STATISTICS_update(plugin->env->stats,
2026  gettext_noop(
2027  "# bytes discarded by TCP (timeout)"),
2028  ret,
2029  GNUNET_NO);
2030  if (0 < ret)
2031  notify_session_monitor(session->plugin,
2032  session,
2034  return 0;
2035  }
2036  /* copy all pending messages that would fit */
2037  ret = 0;
2038  cbuf = buf;
2039  hd = NULL;
2040  tl = NULL;
2041  while (NULL != (pos = session->pending_messages_head))
2042  {
2043  if (ret + pos->message_size > size)
2044  break;
2046  session->pending_messages_tail,
2047  pos);
2048  GNUNET_assert(0 < session->msgs_in_queue);
2049  session->msgs_in_queue--;
2050  GNUNET_assert(pos->message_size <= session->bytes_in_queue);
2051  session->bytes_in_queue -= pos->message_size;
2052  GNUNET_assert(size >= pos->message_size);
2054  "Transmitting message of type %u size %u to peer %s at %s\n",
2055  ntohs(((struct GNUNET_MessageHeader *)pos->msg)->type),
2056  pos->message_size,
2057  GNUNET_i2s(&session->target),
2059  session->address->address,
2060  session->address->address_length));
2061  /* FIXME: this GNUNET_memcpy can be up to 7% of our total runtime */
2062  GNUNET_memcpy(cbuf, pos->msg, pos->message_size);
2063  cbuf += pos->message_size;
2064  ret += pos->message_size;
2065  size -= pos->message_size;
2066  GNUNET_CONTAINER_DLL_insert_tail(hd, tl, pos);
2067  }
2069  /* schedule 'continuation' before callbacks so that callbacks that
2070  * cancel everything don't cause us to use a session that no longer
2071  * exists... */
2072  process_pending_messages(session);
2074  pid = session->target;
2075  /* we'll now call callbacks that may cancel the session; hence
2076  * we should not use 'session' after this point */
2077  while (NULL != (pos = hd))
2078  {
2079  GNUNET_CONTAINER_DLL_remove(hd, tl, pos);
2080  if (NULL != pos->transmit_cont)
2081  pos->transmit_cont(pos->transmit_cont_cls,
2082  &pid,
2083  GNUNET_OK,
2084  pos->message_size,
2085  pos->message_size); /* FIXME: include TCP overhead */
2086  GNUNET_free(pos);
2087  }
2088  GNUNET_assert(NULL == hd);
2089  GNUNET_assert(NULL == tl);
2090  GNUNET_STATISTICS_update(plugin->env->stats,
2091  gettext_noop("# bytes currently in TCP buffers"),
2092  -(int64_t)ret,
2093  GNUNET_NO);
2094  GNUNET_STATISTICS_update(plugin->env->stats,
2095  gettext_noop("# bytes transmitted via TCP"),
2096  ret,
2097  GNUNET_NO);
2098  return ret;
2099 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
size_t address_length
Number of bytes in address.
size_t message_size
So that the gnunet-service-transport can group messages together, these pending messages need to acce...
GNUNET_TRANSPORT_TransmitContinuation transmit_cont
Continuation function to call once the message has been sent.
const void * address
Binary representation of the address (plugin-specific).
void * transmit_cont_cls
Closure for transmit_cont.
unsigned int msgs_in_queue
Number of messages waiting for transmission to this peer.
struct Plugin * plugin
Pointer to the global plugin struct.
struct GNUNET_SERVER_TransmitHandle * transmit_handle
Handle for pending transmission request.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
struct GNUNET_HELLO_Address * address
Address.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
unsigned long long bytes_in_queue
Number of bytes waiting for transmission to this peer.
static int ret
Final status code.
Definition: gnunet-arm.c:89
uint64_t abs_value_us
The actual value.
static void notify_session_monitor(struct Plugin *plugin, struct GNUNET_ATS_Session *session, enum GNUNET_TRANSPORT_SessionState state)
If a session monitor is attached, notify it about the new session state.
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
struct PendingMessage * pending_messages_tail
Messages currently pending for transmission to this peer, if any.
Information about ongoing sessions of the transport client.
struct GNUNET_DATACACHE_PluginEnvironment * env
Our execution environment.
struct PendingMessage * pending_messages_head
Messages currently pending for transmission to this peer, if any.
static char buf[2048]
#define GNUNET_CONTAINER_DLL_insert_after(head, tail, other, element)
Insert an element into a DLL after the given other element.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
struct GNUNET_TIME_Absolute timeout
At what time should we give up on the transmission (and no longer retry)?
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned int size
Size of the "table".
Definition: peer.c:66
static const char * tcp_plugin_address_to_string(void *cls, const void *addr, size_t addrlen)
Function called for a quick conversion of the binary address to a numeric address.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
This is just an update about the session, the state did not change.
The identity of the host (wraps the signing key of the peer).
static void process_pending_messages(struct GNUNET_ATS_Session *session)
If we have pending messages, ask the server to transmit them (schedule the respective tasks...
Handle for a plugin.
Definition: block.c:37
struct GNUNET_PeerIdentity target
To whom are we talking to.
List containing all messages that are yet to be send.
const char * msg
The pending message.
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
struct GNUNET_TIME_Absolute last_activity
Last activity on this connection.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
#define LOG(kind,...)
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_free(ptr)
Wrapper around free.
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tcp_plugin_send()

static ssize_t tcp_plugin_send ( void *  cls,
struct GNUNET_ATS_Session session,
const char *  msgbuf,
size_t  msgbuf_size,
unsigned int  priority,
struct GNUNET_TIME_Relative  to,
GNUNET_TRANSPORT_TransmitContinuation  cont,
void *  cont_cls 
)
static

Function that can be used by the transport service to transmit a message using the plugin.

Note that in the case of a peer disconnecting, the continuation MUST be called prior to the disconnect notification itself. This function will be called with this peer's HELLO message to initiate a fresh connection to another peer.

Parameters
clsclosure
sessionwhich session must be used
msgbufthe message to transmit
msgbuf_sizenumber of bytes in msgbuf
priorityhow important is the message (most plugins will ignore message priority and just FIFO)
tohow long to wait at most for the transmission (does not require plugins to discard the message after the timeout, just advisory for the desired delay; most plugins will ignore this as well)
contcontinuation to call once the message has been transmitted (or if the transport is ready for the next transmission call; or if the peer disconnected...); can be NULL
cont_clsclosure for cont
Returns
number of bytes used (on the physical network, with overheads); -1 on hard errors (i.e. address invalid); 0 is a legal value and does NOT mean that the message was not transmitted (DV)

Definition at line 2157 of file plugin_transport_tcp.c.

References GNUNET_ATS_Session::bytes_in_queue, GNUNET_ATS_Session::client, Plugin::env, gettext_noop, GNUNET_assert, GNUNET_break, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_CONTAINER_multipeermap_contains_value(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_i2s(), GNUNET_malloc, GNUNET_memcpy, GNUNET_NO, GNUNET_SERVER_client_set_timeout(), GNUNET_STATISTICS_update(), GNUNET_SYSERR, GNUNET_TIME_relative_to_absolute(), GNUNET_TRANSPORT_SS_HANDSHAKE, GNUNET_TRANSPORT_SS_UPDATE, GNUNET_YES, LOG, PendingMessage::message_size, PendingMessage::msg, GNUNET_ATS_Session::msgs_in_queue, Plugin::nat_wait_conns, notify_session_monitor(), GNUNET_ATS_Session::pending_messages_head, GNUNET_ATS_Session::pending_messages_tail, plugin, GNUNET_ATS_Session::plugin, pm, process_pending_messages(), Plugin::sessionmap, GNUNET_ATS_Session::target, PendingMessage::timeout, PendingMessage::transmit_cont, and PendingMessage::transmit_cont_cls.

Referenced by libgnunet_plugin_transport_tcp_init().

2165 {
2166  struct Plugin *plugin = cls;
2167  struct PendingMessage *pm;
2168 
2169  /* create new message entry */
2170  pm = GNUNET_malloc(sizeof(struct PendingMessage) + msgbuf_size);
2171  pm->msg = (const char *)&pm[1];
2172  GNUNET_memcpy(&pm[1], msgbuf, msgbuf_size);
2173  pm->message_size = msgbuf_size;
2175  pm->transmit_cont = cont;
2176  pm->transmit_cont_cls = cont_cls;
2177 
2179  "Asked to transmit %u bytes to `%s', added message to list.\n",
2180  msgbuf_size,
2181  GNUNET_i2s(&session->target));
2182 
2183  if (GNUNET_YES ==
2185  &session->target,
2186  session))
2187  {
2188  GNUNET_assert(NULL != session->client);
2191  GNUNET_STATISTICS_update(plugin->env->stats,
2192  gettext_noop("# bytes currently in TCP buffers"),
2193  msgbuf_size,
2194  GNUNET_NO);
2195 
2196  /* append pm to pending_messages list */
2198  session->pending_messages_tail,
2199  pm);
2200  notify_session_monitor(session->plugin,
2201  session,
2203  session->msgs_in_queue++;
2204  session->bytes_in_queue += pm->message_size;
2205  process_pending_messages(session);
2206  return msgbuf_size;
2207  }
2208  if (GNUNET_YES ==
2210  &session->target,
2211  session))
2212  {
2214  "This NAT WAIT session for peer `%s' is not yet ready!\n",
2215  GNUNET_i2s(&session->target));
2216  GNUNET_STATISTICS_update(plugin->env->stats,
2217  gettext_noop("# bytes currently in TCP buffers"),
2218  msgbuf_size,
2219  GNUNET_NO);
2220  /* append pm to pending_messages list */
2222  session->pending_messages_tail,
2223  pm);
2224  session->msgs_in_queue++;
2225  session->bytes_in_queue += pm->message_size;
2226  notify_session_monitor(session->plugin,
2227  session,
2229  return msgbuf_size;
2230  }
2231  LOG(GNUNET_ERROR_TYPE_ERROR, "Invalid session %p\n", session);
2232  if (NULL != cont)
2233  cont(cont_cls, &session->target, GNUNET_SYSERR, pm->message_size, 0);
2234  GNUNET_break(0);
2235  GNUNET_free(pm);
2236  return GNUNET_SYSERR; /* session does not exist here */
2237 }
size_t message_size
So that the gnunet-service-transport can group messages together, these pending messages need to acce...
struct GNUNET_CONTAINER_MultiPeerMap * sessionmap
Map from peer identities to sessions for the given peer.
GNUNET_TRANSPORT_TransmitContinuation transmit_cont
Continuation function to call once the message has been sent.
void * transmit_cont_cls
Closure for transmit_cont.
unsigned int msgs_in_queue
Number of messages waiting for transmission to this peer.
struct Plugin * plugin
Pointer to the global plugin struct.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:246
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Initial session handshake is in progress.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_NO
Definition: gnunet_common.h:78
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
unsigned long long bytes_in_queue
Number of bytes waiting for transmission to this peer.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static void notify_session_monitor(struct Plugin *plugin, struct GNUNET_ATS_Session *session, enum GNUNET_TRANSPORT_SessionState state)
If a session monitor is attached, notify it about the new session state.
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
struct PendingMessage * pending_messages_tail
Messages currently pending for transmission to this peer, if any.
struct GNUNET_DATACACHE_PluginEnvironment * env
Our execution environment.
struct PendingMessage * pending_messages_head
Messages currently pending for transmission to this peer, if any.
void GNUNET_SERVER_client_set_timeout(struct GNUNET_SERVER_Client *client, struct GNUNET_TIME_Relative timeout)
Change the timeout for a particular client.
struct GNUNET_TIME_Absolute timeout
At what time should we give up on the transmission (and no longer retry)?
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT
After how long do we consider a connection to a peer dead if we don&#39;t receive messages from the peer...
This is just an update about the session, the state did not change.
int GNUNET_CONTAINER_multipeermap_contains_value(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Check if the map contains the given value under the given key.
static void process_pending_messages(struct GNUNET_ATS_Session *session)
If we have pending messages, ask the server to transmit them (schedule the respective tasks...
Handle for a plugin.
Definition: block.c:37
struct GNUNET_PeerIdentity target
To whom are we talking to.
List containing all messages that are yet to be send.
const char * msg
The pending message.
struct Client * client
The transport client that provided the session.
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_CONTAINER_MultiPeerMap * nat_wait_conns
Map of peers we have tried to contact behind a NAT.
#define LOG(kind,...)
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
static struct GNUNET_TRANSPORT_PluginMonitor * pm
Handle if we are monitoring plugin session activity.
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ session_lookup_it()

static int session_lookup_it ( void *  cls,
const struct GNUNET_PeerIdentity key,
void *  value 
)
static

Look for a session by address.

Parameters
clsthe struct GNUNET_ATS_SessionItCtx
keyunused
valuea struct GNUNET_ATS_Session
Returns
GNUNET_YES to continue looking, GNUNET_NO if we found the session

Definition at line 2265 of file plugin_transport_tcp.c.

References GNUNET_ATS_Session::address, GNUNET_ATS_SessionItCtx::address, GNUNET_HELLO_address_cmp(), GNUNET_NO, GNUNET_YES, GNUNET_ATS_SessionItCtx::result, and value.

Referenced by tcp_plugin_get_session().

2268 {
2269  struct GNUNET_ATS_SessionItCtx *si_ctx = cls;
2270  struct GNUNET_ATS_Session *session = value;
2271 
2272  if (0 != GNUNET_HELLO_address_cmp(si_ctx->address, session->address))
2273  return GNUNET_YES;
2274  si_ctx->result = session;
2275  return GNUNET_NO;
2276 }
#define GNUNET_NO
Definition: gnunet_common.h:78
struct GNUNET_HELLO_Address * address
Address.
struct GNUNET_ATS_Session * result
Where to store the session (if we found it).
int GNUNET_HELLO_address_cmp(const struct GNUNET_HELLO_Address *a1, const struct GNUNET_HELLO_Address *a2)
Compare two addresses.
Definition: address.c:130
static char * value
Value of the record to add/remove.
Information about ongoing sessions of the transport client.
Closure for session_lookup_it().
const struct GNUNET_HELLO_Address * address
Address we are looking for.
#define GNUNET_YES
Definition: gnunet_common.h:77
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nat_connect_timeout()

static void nat_connect_timeout ( void *  cls)
static

Task cleaning up a NAT connection attempt after timeout.

Parameters
clsthe struct GNUNET_ATS_Session

Definition at line 2285 of file plugin_transport_tcp.c.

References GNUNET_HELLO_Address::address, GNUNET_ATS_Session::address, GNUNET_HELLO_Address::address_length, GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), LOG, GNUNET_ATS_Session::nat_connection_timeout, GNUNET_ATS_Session::plugin, GNUNET_ATS_Session::target, tcp_plugin_address_to_string(), and tcp_plugin_disconnect_session().

Referenced by tcp_plugin_get_session().

2286 {
2287  struct GNUNET_ATS_Session *session = cls;
2288 
2289  session->nat_connection_timeout = NULL;
2291  "NAT WAIT connection to `%4s' at `%s' could not be established, removing session\n",
2292  GNUNET_i2s(&session->target),
2294  session->address->address,
2295  session->address->address_length));
2296  tcp_plugin_disconnect_session(session->plugin, session);
2297 }
size_t address_length
Number of bytes in address.
const void * address
Binary representation of the address (plugin-specific).
struct Plugin * plugin
Pointer to the global plugin struct.
struct GNUNET_SCHEDULER_Task * nat_connection_timeout
Task cleaning up a NAT client connection establishment attempt;.
struct GNUNET_HELLO_Address * address
Address.
static int tcp_plugin_disconnect_session(void *cls, struct GNUNET_ATS_Session *session)
Functions with this signature are called whenever we need to close a session due to a disconnect or f...
Information about ongoing sessions of the transport client.
static const char * tcp_plugin_address_to_string(void *cls, const void *addr, size_t addrlen)
Function called for a quick conversion of the binary address to a numeric address.
struct GNUNET_PeerIdentity target
To whom are we talking to.
#define LOG(kind,...)
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tcp_plugin_update_session_timeout()

static void tcp_plugin_update_session_timeout ( void *  cls,
const struct GNUNET_PeerIdentity peer,
struct GNUNET_ATS_Session session 
)
static

Function that will be called whenever the transport service wants to notify the plugin that a session is still active and in use and therefore the session timeout for this session has to be updated.

Parameters
clsclosure
peerwhich peer was the session for
sessionwhich session is being updated

Definition at line 2310 of file plugin_transport_tcp.c.

References reschedule_session_timeout().

Referenced by libgnunet_plugin_transport_tcp_init().

2313 {
2314  reschedule_session_timeout(session);
2315 }
static void reschedule_session_timeout(struct GNUNET_ATS_Session *s)
Increment session timeout due to activity.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ delayed_done()

static void delayed_done ( void *  cls)
static

Task to signal the server that we can continue receiving from the TCP client now.

Parameters
clsthe struct GNUNET_ATS_Session *

Definition at line 2325 of file plugin_transport_tcp.c.

References GNUNET_ATS_Session::client, GNUNET_OK, GNUNET_SERVER_receive_done(), GNUNET_ATS_Session::receive_delay_task, and reschedule_session_timeout().

Referenced by handle_tcp_data(), and tcp_plugin_update_inbound_delay().

2326 {
2327  struct GNUNET_ATS_Session *session = cls;
2328 
2329  session->receive_delay_task = NULL;
2330  reschedule_session_timeout(session);
2332 }
struct GNUNET_SCHEDULER_Task * receive_delay_task
ID of task used to delay receiving more to throttle sender.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
Information about ongoing sessions of the transport client.
void GNUNET_SERVER_receive_done(struct GNUNET_SERVER_Client *client, int success)
Resume receiving from this client, we are done processing the current request.
struct Client * client
The transport client that provided the session.
static void reschedule_session_timeout(struct GNUNET_ATS_Session *s)
Increment session timeout due to activity.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tcp_plugin_update_inbound_delay()

static void tcp_plugin_update_inbound_delay ( void *  cls,
const struct GNUNET_PeerIdentity peer,
struct GNUNET_ATS_Session session,
struct GNUNET_TIME_Relative  delay 
)
static

Function that will be called whenever the transport service wants to notify the plugin that the inbound quota changed and that the plugin should update it's delay for the next receive value.

Parameters
clsclosure
peerwhich peer was the session for
sessionwhich session is being updated
delaynew delay to use for receiving

Definition at line 2346 of file plugin_transport_tcp.c.

References delayed_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_cancel(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_relative_to_absolute(), LOG, GNUNET_ATS_Session::receive_delay, and GNUNET_ATS_Session::receive_delay_task.

Referenced by libgnunet_plugin_transport_tcp_init().

2350 {
2351  if (NULL == session->receive_delay_task)
2352  return;
2354  "New inbound delay %s\n",
2358  session->receive_delay_task =
2359  GNUNET_SCHEDULER_add_delayed(delay, &delayed_done, session);
2360 }
struct GNUNET_TIME_Absolute receive_delay
When will we continue to read from the socket? (used to enforce inbound quota).
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:246
struct GNUNET_SCHEDULER_Task * receive_delay_task
ID of task used to delay receiving more to throttle sender.
static void delayed_done(void *cls)
Task to signal the server that we can continue receiving from the TCP client now. ...
#define GNUNET_NO
Definition: gnunet_common.h:78
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1237
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:686
#define LOG(kind,...)
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tcp_plugin_get_session()

static struct GNUNET_ATS_Session* tcp_plugin_get_session ( void *  cls,
const struct GNUNET_HELLO_Address address 
)
static

Create a new session to transmit data to the target This session will used to send data to this peer and the plugin will notify us by calling the env->session_end function.

Parameters
clsclosure
addressthe address to use
Returns
the session if the address is valid, NULL otherwise

Definition at line 2373 of file plugin_transport_tcp.c.

References GNUNET_HELLO_Address::address, address, GNUNET_ATS_SessionItCtx::address, GNUNET_HELLO_Address::address_length, GNUNET_DATACACHE_PluginEnvironment::cls, create_session(), Plugin::cur_connections, Plugin::env, gettext_noop, GNUNET_a2s(), GNUNET_assert, GNUNET_break, GNUNET_CONNECTION_connect_socket(), GNUNET_CONNECTION_create_from_sockaddr(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CONTAINER_multipeermap_contains(), GNUNET_CONTAINER_multipeermap_get_multiple(), GNUNET_CONTAINER_multipeermap_put(), GNUNET_ERROR_TYPE_BULK, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_HELLO_address_check_option(), GNUNET_HELLO_ADDRESS_INFO_INBOUND, GNUNET_i2s(), GNUNET_log_strerror, GNUNET_memcpy, GNUNET_NAT_request_reversal(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_create(), GNUNET_NETWORK_socket_setsockopt(), GNUNET_NO, GNUNET_NT_UNSPECIFIED, GNUNET_OK, GNUNET_SCHEDULER_add_delayed(), GNUNET_SERVER_connect_socket(), GNUNET_STATISTICS_update(), GNUNET_YES, IPv4TcpAddress::ipv4_addr, IPv6TcpAddress::ipv6_addr, LOG, Plugin::max_connections, Plugin::my_welcome, Plugin::nat, nat_connect_timeout(), GNUNET_ATS_Session::nat_connection_timeout, NAT_TIMEOUT, Plugin::nat_wait_conns, Plugin::open_port, options, IPv4TcpAddress::options, IPv6TcpAddress::options, GNUNET_HELLO_Address::peer, plugin, process_pending_messages(), GNUNET_ATS_SessionItCtx::result, Plugin::server, session_lookup_it(), Plugin::sessionmap, t4, IPv4TcpAddress::t4_port, t6, IPv6TcpAddress::t6_port, GNUNET_ATS_Session::target, TCP_OPTIONS_TCP_STEALTH, tcp_plugin_address_to_string(), and tcp_plugin_disconnect_session().

Referenced by libgnunet_plugin_transport_tcp_init().

2374 {
2375  struct Plugin *plugin = cls;
2376  struct GNUNET_ATS_Session *session = NULL;
2377  int af;
2378  const void *sb;
2379  size_t sbs;
2380  struct GNUNET_CONNECTION_Handle *sa;
2381  struct sockaddr_in a4;
2382  struct sockaddr_in6 a6;
2383  const struct IPv4TcpAddress *t4;
2384  const struct IPv6TcpAddress *t6;
2385  unsigned int options;
2386  enum GNUNET_NetworkType net_type;
2387  unsigned int is_natd = GNUNET_NO;
2388  size_t addrlen;
2389 
2390 #ifdef TCP_STEALTH
2391  struct GNUNET_NETWORK_Handle *s;
2392 #endif
2393 
2394  addrlen = address->address_length;
2396  "Trying to get session for `%s' address of peer `%s'\n",
2398  address->address,
2399  address->address_length),
2400  GNUNET_i2s(&address->peer));
2401 
2404  {
2405  GNUNET_break(0);
2406  return NULL;
2407  }
2408 
2409  /* look for existing session */
2411  &address->peer))
2412  {
2413  struct GNUNET_ATS_SessionItCtx si_ctx;
2414 
2415  si_ctx.address = address;
2416  si_ctx.result = NULL;
2418  &address->peer,
2420  &si_ctx);
2421  if (NULL != si_ctx.result)
2422  {
2423  session = si_ctx.result;
2425  "Found existing session for `%s' address `%s'\n",
2426  GNUNET_i2s(&address->peer),
2428  address->address,
2429  address->address_length));
2430  return session;
2431  }
2432  /* This is a bit of a hack, limiting TCP to never allow more than
2433  one TCP connection to any given peer at the same time.
2434  Without this, peers sometimes disagree about which of the TCP
2435  connections they should use, causing one side to believe that
2436  they transmit successfully, while the other receives nothing. */
2437  return NULL; /* Refuse to have more than one TCP connection per
2438  peer pair at the same time. */
2439  }
2440 
2441  if (addrlen == sizeof(struct IPv6TcpAddress))
2442  {
2443  GNUNET_assert(NULL != address->address); /* make static analysis happy */
2444  t6 = address->address;
2445  options = t6->options;
2446  af = AF_INET6;
2447  memset(&a6, 0, sizeof(a6));
2448 #if HAVE_SOCKADDR_IN_SIN_LEN
2449  a6.sin6_len = sizeof(a6);
2450 #endif
2451  a6.sin6_family = AF_INET6;
2452  a6.sin6_port = t6->t6_port;
2453  if (t6->t6_port == 0)
2454  is_natd = GNUNET_YES;
2455  GNUNET_memcpy(&a6.sin6_addr, &t6->ipv6_addr, sizeof(struct in6_addr));
2456  sb = &a6;
2457  sbs = sizeof(a6);
2458  }
2459  else if (addrlen == sizeof(struct IPv4TcpAddress))
2460  {
2461  GNUNET_assert(NULL != address->address); /* make static analysis happy */
2462  t4 = address->address;
2463  options = t4->options;
2464  af = AF_INET;
2465  memset(&a4, 0, sizeof(a4));
2466 #if HAVE_SOCKADDR_IN_SIN_LEN
2467  a4.sin_len = sizeof(a4);
2468 #endif
2469  a4.sin_family = AF_INET;
2470  a4.sin_port = t4->t4_port;
2471  if (t4->t4_port == 0)
2472  is_natd = GNUNET_YES;
2473  a4.sin_addr.s_addr = t4->ipv4_addr;
2474  sb = &a4;
2475  sbs = sizeof(a4);
2476  }
2477  else
2478  {
2480  plugin->env->stats,
2481  gettext_noop("# requests to create session with invalid address"),
2482  1,
2483  GNUNET_NO);
2484  return NULL;
2485  }
2486 
2487  net_type = plugin->env->get_address_type(plugin->env->cls, sb, sbs);
2488  GNUNET_break(net_type != GNUNET_NT_UNSPECIFIED);
2489 
2490  if ((is_natd == GNUNET_YES) && (addrlen == sizeof(struct IPv6TcpAddress)))
2491  {
2492  /* NAT client only works with IPv4 addresses */
2493  return NULL;
2494  }
2495 
2496  if (plugin->cur_connections >= plugin->max_connections)
2497  {
2498  /* saturated */
2499  return NULL;
2500  }
2501 
2502  if ((is_natd == GNUNET_YES) &&
2503  (GNUNET_YES ==
2505  &address->peer)))
2506  {
2507  /* Only do one NAT punch attempt per peer identity */
2508  return NULL;
2509  }
2510 
2511  if ((is_natd == GNUNET_YES) && (NULL != plugin->nat) &&
2512  (GNUNET_NO ==
2514  &address->peer)))
2515  {
2516  struct sockaddr_in local_sa;
2517 
2519  "Found valid IPv4 NAT address (creating session)!\n");
2520  session = create_session(plugin, address, net_type, NULL, GNUNET_YES);
2521  session->nat_connection_timeout =
2525  plugin->nat_wait_conns,
2526  &session->target,
2527  session,
2529 
2531  "Created NAT WAIT connection to `%s' at `%s'\n",
2532  GNUNET_i2s(&session->target),
2533  GNUNET_a2s(sb, sbs));
2534  memset(&local_sa, 0, sizeof(local_sa));
2535  local_sa.sin_family = AF_INET;
2536  local_sa.sin_port = htons(plugin->open_port);
2537  /* We leave sin_address at 0, let the kernel figure it out,
2538  even if our bind() is more specific. (May want to reconsider
2539  later.) */
2540  if (GNUNET_OK == GNUNET_NAT_request_reversal(plugin->nat, &local_sa, &a4))
2541  return session;
2543  "Running NAT client for `%s' at `%s' failed\n",
2544  GNUNET_i2s(&session->target),
2545  GNUNET_a2s(sb, sbs));
2546  tcp_plugin_disconnect_session(plugin, session);
2547  return NULL;
2548  }
2549 
2550  /* create new outbound session */
2551  if (0 != (options & TCP_OPTIONS_TCP_STEALTH))
2552  {
2553 #ifdef TCP_STEALTH
2554  s = GNUNET_NETWORK_socket_create(af, SOCK_STREAM, 0);
2555  if (NULL == s)
2556  {
2558  "socket");
2559  sa = NULL;
2560  }
2561  else
2562  {
2563  if ((GNUNET_OK !=
2565  IPPROTO_TCP,
2566  TCP_STEALTH,
2567  &session->target,
2568  sizeof(
2569  struct GNUNET_PeerIdentity))) ||
2570  (GNUNET_OK !=
2572  IPPROTO_TCP,
2573  TCP_STEALTH_INTEGRITY,
2574  &plugin->my_welcome,
2575  sizeof(struct WelcomeMessage))))
2576  {
2577  /* TCP STEALTH not supported by kernel */
2579  sa = NULL;
2580  }
2581  else
2582  {
2583  sa = GNUNET_CONNECTION_connect_socket(s, sb, sbs);
2584  }
2585  }
2586 #else
2587  sa = NULL;
2588 #endif
2589  }
2590  else
2591  {
2592  sa = GNUNET_CONNECTION_create_from_sockaddr(af, sb, sbs);
2593  }
2594  if (NULL == sa)
2595  {
2597  "Failed to create connection to `%s' at `%s'\n",
2598  GNUNET_i2s(&address->peer),
2599  GNUNET_a2s(sb, sbs));
2600  return NULL;
2601  }
2603  "Asked to transmit to `%s', creating fresh session using address `%s'.\n",
2604  GNUNET_i2s(&address->peer),
2605  GNUNET_a2s(sb, sbs));
2606 
2607  session = create_session(plugin,
2608  address,
2609  net_type,
2610  GNUNET_SERVER_connect_socket(plugin->server, sa),
2611  GNUNET_NO);
2613  plugin->sessionmap,
2614  &session->target,
2615  session,
2617  /* Send TCP Welcome */
2618  process_pending_messages(session);
2619 
2620  return session;
2621 }
size_t address_length
Number of bytes in address.
struct GNUNET_NAT_Handle * nat
NAT handle & address management.
int GNUNET_NETWORK_socket_setsockopt(struct GNUNET_NETWORK_Handle *fd, int level, int option_name, const void *option_value, socklen_t option_len)
Set socket option.
Definition: network.c:871
int max_connections
Maximum number of sockets the plugin can use Each http inbound /outbound connections are two connecti...
struct GNUNET_CONTAINER_MultiPeerMap * sessionmap
Map from peer identities to sessions for the given peer.
const void * address
Binary representation of the address (plugin-specific).
int GNUNET_NAT_request_reversal(struct GNUNET_NAT_Handle *nh, const struct sockaddr_in *local_sa, const struct sockaddr_in *remote_sa)
We learned about a peer (possibly behind NAT) so run the gnunet-nat-client to send dummy ICMP respons...
Definition: nat_api.c:655
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
struct GNUNET_CONNECTION_Handle * GNUNET_CONNECTION_connect_socket(struct GNUNET_NETWORK_Handle *s, const struct sockaddr *serv_addr, socklen_t addrlen)
Create a connection handle by (asynchronously) connecting to a host.
uint16_t open_port
Port that we are actually listening on.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_SCHEDULER_Task * nat_connection_timeout
Task cleaning up a NAT client connection establishment attempt;.
static struct GNUNET_ATS_Session * create_session(struct Plugin *plugin, const struct GNUNET_HELLO_Address *address, enum GNUNET_NetworkType scope, struct GNUNET_SERVER_Client *client, int is_nat)
Create a new session.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
uint32_t options
Optional flags for this address see enum TcpAddressOptions
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
Definition: gnunet_nt_lib.h:35
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
int cur_connections
Current number of establishes connections.
int GNUNET_HELLO_address_check_option(const struct GNUNET_HELLO_Address *address, enum GNUNET_HELLO_AddressInfo option)
Check if an address has a local option set.
Definition: address.c:39
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
struct GNUNET_SERVER_Client * GNUNET_SERVER_connect_socket(struct GNUNET_SERVER_Handle *server, struct GNUNET_CONNECTION_Handle *connection)
Add a TCP socket-based connection to the set of handles managed by this server.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1237
Network format for IPv4 addresses.
uint32_t options
Optional options and flags for this address, see enum TcpAddressOptions
static int tcp_plugin_disconnect_session(void *cls, struct GNUNET_ATS_Session *session)
Functions with this signature are called whenever we need to close a session due to a disconnect or f...
Information about ongoing sessions of the transport client.
This is an inbound address and cannot be used to initiate an outbound connection to another peer...
struct GNUNET_DATACACHE_PluginEnvironment * env
Our execution environment.
static struct GNUNET_SCHEDULER_Task * t4
Task for IPv4 socket.
struct GNUNET_CONNECTION_Handle * GNUNET_CONNECTION_create_from_sockaddr(int af_family, const struct sockaddr *serv_addr, socklen_t addrlen)
Create a connection handle by creating a socket and (asynchronously) connecting to a host...
const char * GNUNET_a2s(const struct sockaddr *addr, socklen_t addrlen)
Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string (for printing debug messages)...
Closure for session_lookup_it().
Network format for IPv6 addresses.
const struct GNUNET_HELLO_Address * address
Address we are looking for.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
struct in6_addr ipv6_addr
IPv6 address.
static const char * tcp_plugin_address_to_string(void *cls, const void *addr, size_t addrlen)
Function called for a quick conversion of the binary address to a numeric address.
static int session_lookup_it(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Look for a session by address.
struct GNUNET_PeerIdentity peer
For which peer is this an address?
Allow multiple values with the same key.
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
The identity of the host (wraps the signing key of the peer).
static void process_pending_messages(struct GNUNET_ATS_Session *session)
If we have pending messages, ask the server to transmit them (schedule the respective tasks...
Handle for a plugin.
Definition: block.c:37
struct GNUNET_PeerIdentity target
To whom are we talking to.
Initial handshake message for a session.
struct WelcomeMessage my_welcome
Welcome message used by this peer.
uint16_t t4_port
Port number, in network byte order.
handle to a socket
Definition: network.c:46
void * cls
Closure to use for callbacks.
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_CONTAINER_MultiPeerMap * nat_wait_conns
Map of peers we have tried to contact behind a NAT.
#define NAT_TIMEOUT
How long until we give up on establishing an NAT connection? Must be > 4 RTT.
Enable TCP Stealth-style port knocking.
uint32_t ipv4_addr
IPv4 address, in network byte order.
#define LOG(kind,...)
handle for a network connection
int GNUNET_CONTAINER_multipeermap_contains(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Check if the map contains any value under the given key (including values that are NULL)...
static char * address
GNS address for this phone.
struct GNUNET_SERVER_Handle * server
Handle to the server for this service.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:548
int GNUNET_CONTAINER_multipeermap_get_multiple(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map that match a particular key.
uint16_t t6_port
Port number, in network byte order.
static struct GNUNET_SCHEDULER_Task * t6
Task for IPv6 socket.
#define gettext_noop(String)
Definition: gettext.h:69
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:900
Category of last resort.
Definition: gnunet_nt_lib.h:39
static void nat_connect_timeout(void *cls)
Task cleaning up a NAT connection attempt after timeout.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ session_disconnect_it()

static int session_disconnect_it ( void *  cls,
const struct GNUNET_PeerIdentity key,
void *  value 
)
static

We have been asked to destroy all connections to a particular peer.

This function is called on each applicable session and must tear it down.

Parameters
clsthe struct Plugin *
keythe peer which the session belongs to (unused)
valuethe struct GNUNET_ATS_Session
Returns
GNUNET_YES (continue to iterate)

Definition at line 2635 of file plugin_transport_tcp.c.

References Plugin::env, gettext_noop, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_YES, plugin, GNUNET_ATS_Session::plugin, tcp_plugin_disconnect_session(), and value.

Referenced by libgnunet_plugin_transport_tcp_done(), and tcp_plugin_disconnect().

2638 {
2639  struct Plugin *plugin = cls;
2640  struct GNUNET_ATS_Session *session = value;
2641 
2642  GNUNET_STATISTICS_update(session->plugin->env->stats,
2643  gettext_noop(
2644  "# transport-service disconnect requests for TCP"),
2645  1,
2646  GNUNET_NO);
2647  tcp_plugin_disconnect_session(plugin, session);
2648  return GNUNET_YES;
2649 }
struct Plugin * plugin
Pointer to the global plugin struct.
#define GNUNET_NO
Definition: gnunet_common.h:78
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
static int tcp_plugin_disconnect_session(void *cls, struct GNUNET_ATS_Session *session)
Functions with this signature are called whenever we need to close a session due to a disconnect or f...
static char * value
Value of the record to add/remove.
Information about ongoing sessions of the transport client.
struct GNUNET_DATACACHE_PluginEnvironment * env
Our execution environment.
Handle for a plugin.
Definition: block.c:37
#define GNUNET_YES
Definition: gnunet_common.h:77
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tcp_plugin_disconnect()

static void tcp_plugin_disconnect ( void *  cls,
const struct GNUNET_PeerIdentity target 
)
static

Function that can be called to force a disconnect from the specified neighbour.

This should also cancel all previously scheduled transmissions. Obviously the transmission may have been partially completed already, which is OK. The plugin is supposed to close the connection (if applicable) and no longer call the transmit continuation(s).

Finally, plugin MUST NOT call the services's receive function to notify the service that the connection to the specified target was closed after a getting this call.

Parameters
clsclosure
targetpeer for which the last transmission is to be cancelled

Definition at line 2669 of file plugin_transport_tcp.c.

References GNUNET_CONTAINER_multipeermap_get_multiple(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), LOG, Plugin::nat_wait_conns, plugin, session_disconnect_it(), and Plugin::sessionmap.

Referenced by libgnunet_plugin_transport_tcp_init().

2670 {
2671  struct Plugin *plugin = cls;
2672 
2674  "Disconnecting peer `%s'\n",
2675  GNUNET_i2s(target));
2677  target,
2679  plugin);
2681  target,
2683  plugin);
2684 }
struct GNUNET_CONTAINER_MultiPeerMap * sessionmap
Map from peer identities to sessions for the given peer.
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
static int session_disconnect_it(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
We have been asked to destroy all connections to a particular peer.
Handle for a plugin.
Definition: block.c:37
struct GNUNET_CONTAINER_MultiPeerMap * nat_wait_conns
Map of peers we have tried to contact behind a NAT.
#define LOG(kind,...)
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
int GNUNET_CONTAINER_multipeermap_get_multiple(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map that match a particular key.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ append_port()

static void append_port ( void *  cls,
const char *  hostname 
)
static

We are processing an address pretty printing request and finished the IP resolution (if applicable).

Append our port and forward the result. If called with hostname NULL, we are done and should clean up the pretty printer (otherwise, there might be multiple hostnames for the IP address and we might receive more).

Parameters
clsthe struct PrettyPrinterContext *
hostnamehostname part of the address

Definition at line 2698 of file plugin_transport_tcp.c.

References PrettyPrinterContext::asc, PrettyPrinterContext::asc_cls, GNUNET_asprintf(), GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_OK, GNUNET_YES, PrettyPrinterContext::ipv6, PrettyPrinterContext::options, plugin, PrettyPrinterContext::plugin, PLUGIN_NAME, PrettyPrinterContext::port, Plugin::ppc_dll_head, Plugin::ppc_dll_tail, PrettyPrinterContext::resolver_handle, and ret.

Referenced by tcp_plugin_address_pretty_printer().

2699 {
2700  struct PrettyPrinterContext *ppc = cls;
2701  struct Plugin *plugin = ppc->plugin;
2702  char *ret;
2703 
2705  "append_port called with hostname `%s'\n",
2706  hostname);
2707  if (NULL == hostname)
2708  {
2709  /* Final call, done */
2710  ppc->resolver_handle = NULL;
2712  plugin->ppc_dll_tail,
2713  ppc);
2714  ppc->asc(ppc->asc_cls, NULL, GNUNET_OK);
2715  GNUNET_free(ppc);
2716  return;
2717  }
2718  if (GNUNET_YES == ppc->ipv6)
2719  GNUNET_asprintf(&ret,
2720  "%s.%u.[%s]:%d",
2721  PLUGIN_NAME,
2722  ppc->options,
2723  hostname,
2724  ppc->port);
2725  else
2726  GNUNET_asprintf(&ret,
2727  "%s.%u.%s:%d",
2728  PLUGIN_NAME,
2729  ppc->options,
2730  hostname,
2731  ppc->port);
2732  ppc->asc(ppc->asc_cls, ret, GNUNET_OK);
2733  GNUNET_free(ret);
2734 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
GNUNET_TRANSPORT_AddressStringCallback asc
Function to call with the result.
struct PrettyPrinterContext * ppc_dll_tail
Running pretty printers: tail.
struct GNUNET_RESOLVER_RequestHandle * resolver_handle
Resolver handle.
Closure for append_port().
uint16_t port
Port to add after the IP address.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
void * asc_cls
Clsoure for asc.
static int ret
Final status code.
Definition: gnunet-arm.c:89
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
#define PLUGIN_NAME
static char * hostname
Our hostname; we give this to all the peers we start.
Handle for a plugin.
Definition: block.c:37
uint32_t options
Address options.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:77
struct PrettyPrinterContext * ppc_dll_head
Running pretty printers: head.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tcp_plugin_address_pretty_printer()

static void tcp_plugin_address_pretty_printer ( void *  cls,
const char *  type,
const void *  addr,
size_t  addrlen,
int  numeric,
struct GNUNET_TIME_Relative  timeout,
GNUNET_TRANSPORT_AddressStringCallback  asc,
void *  asc_cls 
)
static

Convert the transports address to a nice, human-readable format.

Parameters
clsclosure with the struct Plugin
typename of the transport that generated the address
addrone of the addresses of the host, NULL for the last address the specific address format depends on the transport
addrlenlength of the addr
numericshould (IP) addresses be displayed in numeric form?
timeoutafter how long should we give up?
ascfunction to call on each string
asc_clsclosure for asc

Definition at line 2751 of file plugin_transport_tcp.c.

References _, append_port(), PrettyPrinterContext::asc, PrettyPrinterContext::asc_cls, GNUNET_break, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log, GNUNET_memcpy, GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_RESOLVER_hostname_get(), GNUNET_SYSERR, GNUNET_YES, IPv4TcpAddress::ipv4_addr, PrettyPrinterContext::ipv6, IPv6TcpAddress::ipv6_addr, LOG, options, PrettyPrinterContext::options, IPv4TcpAddress::options, IPv6TcpAddress::options, plugin, PrettyPrinterContext::plugin, port, PrettyPrinterContext::port, Plugin::ppc_dll_head, Plugin::ppc_dll_tail, PrettyPrinterContext::resolver_handle, t4, IPv4TcpAddress::t4_port, t6, and IPv6TcpAddress::t6_port.

Referenced by libgnunet_plugin_transport_tcp_init().

2759 {
2760  struct Plugin *plugin = cls;
2761  struct PrettyPrinterContext *ppc;
2762  const void *sb;
2763  size_t sbs;
2764  struct sockaddr_in a4;
2765  struct sockaddr_in6 a6;
2766  const struct IPv4TcpAddress *t4;
2767  const struct IPv6TcpAddress *t6;
2768  uint16_t port;
2769  uint32_t options;
2770 
2771  if (sizeof(struct IPv6TcpAddress) == addrlen)
2772  {
2773  t6 = addr;
2774  memset(&a6, 0, sizeof(a6));
2775  a6.sin6_family = AF_INET6;