GNUnet  0.19.4
plugin_transport_unix.c File Reference

Transport plugin using unix domain sockets (!) Clearly, can only be used locally on Unix/Linux hosts... More...

Include dependency graph for plugin_transport_unix.c:

Go to the source code of this file.

Data Structures

struct  UnixAddress
 Binary format for an UNIX Domain Socket address in GNUnet. More...
 
struct  UNIXMessage
 UNIX Message-Packet header. More...
 
struct  UNIXMessageWrapper
 Information we track for a message awaiting transmission. More...
 
struct  GNUNET_ATS_Session
 Session handle for connections. More...
 
struct  UNIX_Sock_Info
 Information we keep for each of our listen sockets. More...
 
struct  Plugin
 Handle for a plugin. More...
 
struct  LookupCtx
 Closure to lookup_queue_it(). More...
 

Macros

#define RETRY   0
 Return code we give on 'send' if we failed to send right now but it makes sense to retry later. More...
 
#define PLUGIN_NAME   "unix"
 Name of the plugin. More...
 
#define HOSTNAME_RESOLVE_TIMEOUT    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
 How long until we give up on transmitting the welcome message? More...
 
#define LOG(kind, ...)   GNUNET_log_from (kind, "transport-unix", __VA_ARGS__)
 

Enumerations

enum  UNIX_ADDRESS_OPTIONS { UNIX_OPTIONS_NONE = 0 , UNIX_OPTIONS_USE_ABSTRACT_SOCKETS = 1 }
 Options for UNIX Domain addresses. More...
 

Functions

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 const char * unix_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 unix_plugin_session_disconnect (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 void session_timeout (void *cls)
 Session was idle for too long, so disconnect it. More...
 
static void reschedule_session_timeout (struct GNUNET_ATS_Session *session)
 Increment session timeout due to activity. More...
 
static struct sockaddr_un * unix_address_to_sockaddr (const char *unixpath, socklen_t *sock_len)
 Convert unix path to a struct sockaddr_un * More...
 
static int lookup_session_it (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
 Function called to find a session by address. More...
 
static struct GNUNET_ATS_Sessionlookup_session (struct Plugin *plugin, const struct GNUNET_HELLO_Address *address)
 Find an existing session by address. More...
 
static unsigned int unix_plugin_query_keepalive_factor (void *cls)
 Function that is called to get the keepalive factor. More...
 
static ssize_t unix_real_send (void *cls, struct GNUNET_NETWORK_Handle *send_handle, const struct GNUNET_PeerIdentity *target, const char *msgbuf, size_t msgbuf_size, unsigned int priority, struct GNUNET_TIME_Absolute timeout, const struct UnixAddress *addr, size_t addrlen, size_t payload, GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
 Actually send out the message, assume we've got the address and send_handle squared away! More...
 
static enum GNUNET_NetworkType unix_plugin_get_network (void *cls, struct GNUNET_ATS_Session *session)
 Function obtain the network type for a session. More...
 
static enum GNUNET_NetworkType unix_plugin_get_network_for_address (void *cls, const struct GNUNET_HELLO_Address *address)
 Function obtain the network type for a session. More...
 
static struct GNUNET_ATS_Sessionunix_plugin_get_session (void *cls, const struct GNUNET_HELLO_Address *address)
 Creates a new outbound session the transport service will use to send data to the peer. More...
 
static void unix_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 unix_demultiplexer (struct Plugin *plugin, struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *currhdr, const struct UnixAddress *ua, size_t ua_len)
 Demultiplexer for UNIX messages. More...
 
static void unix_plugin_do_read (struct Plugin *plugin)
 Read from UNIX domain socket (it is ready). More...
 
static void unix_plugin_do_write (struct Plugin *plugin)
 Write to UNIX domain socket (it is ready). More...
 
static void unix_plugin_select_read (void *cls)
 We have been notified that our socket has something to read. More...
 
static void unix_plugin_select_write (void *cls)
 We have been notified that our socket is ready to write. More...
 
static ssize_t unix_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 unix_transport_server_start (void *cls)
 Create a slew of UNIX sockets. More...
 
static int unix_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 unix_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 unix_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 void address_notification (void *cls)
 Notify transport service about address. More...
 
static int get_session_delete_it (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
 Function called on sessions to disconnect. More...
 
static void unix_plugin_peer_disconnect (void *cls, const struct GNUNET_PeerIdentity *target)
 Disconnect from a remote node. 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 unix_plugin_setup_monitor (void *cls, GNUNET_TRANSPORT_SessionInfoCallback sic, void *sic_cls)
 Begin monitoring sessions of a plugin. More...
 
void * libgnunet_plugin_transport_unix_init (void *cls)
 The exported method. More...
 
void * libgnunet_plugin_transport_unix_done (void *cls)
 Shutdown the plugin. More...
 

Detailed Description

Transport plugin using unix domain sockets (!) Clearly, can only be used locally on Unix/Linux hosts...

ONLY INTENDED FOR TESTING!!!

Author
Christian Grothoff
Nathan Evans

Definition in file plugin_transport_unix.c.

Macro Definition Documentation

◆ RETRY

#define RETRY   0

Return code we give on 'send' if we failed to send right now but it makes sense to retry later.

(Note: we might want to move this to the plugin API!?).

Definition at line 44 of file plugin_transport_unix.c.

◆ PLUGIN_NAME

#define PLUGIN_NAME   "unix"

Name of the plugin.

Definition at line 49 of file plugin_transport_unix.c.

◆ HOSTNAME_RESOLVE_TIMEOUT

#define HOSTNAME_RESOLVE_TIMEOUT    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)

How long until we give up on transmitting the welcome message?

Definition at line 71 of file plugin_transport_unix.c.

◆ LOG

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

Definition at line 74 of file plugin_transport_unix.c.

Enumeration Type Documentation

◆ UNIX_ADDRESS_OPTIONS

Options for UNIX Domain addresses.

Enumerator
UNIX_OPTIONS_NONE 

No special options.

UNIX_OPTIONS_USE_ABSTRACT_SOCKETS 

Linux abstract domain sockets should be used.

Definition at line 54 of file plugin_transport_unix.c.

55 {
60 
65 };
@ UNIX_OPTIONS_USE_ABSTRACT_SOCKETS
Linux abstract domain sockets should be used.
@ UNIX_OPTIONS_NONE
No special options.

Function Documentation

◆ 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 333 of file plugin_transport_unix.c.

336 {
338 
339  if (NULL == plugin->sic)
340  return;
341  memset (&info, 0, sizeof(info));
342  info.state = state;
343  info.is_inbound = GNUNET_SYSERR; /* hard to say */
344  info.num_msg_pending = session->msgs_in_queue;
345  info.num_bytes_pending = session->bytes_in_queue;
346  /* info.receive_delay remains zero as this is not supported by UNIX
347  (cannot selectively not receive from 'some' peer while continuing
348  to receive from others) */
349  info.session_timeout = session->timeout;
350  info.address = session->address;
351  plugin->sic (plugin->sic_cls, session, &info);
352 }
struct TestcasePlugin * plugin
The process handle to the testbed service.
enum State state
current state of profiling
#define info
@ GNUNET_SYSERR
unsigned int msgs_in_queue
Number of messages waiting for transmission to this peer.
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.
Information about a plugin's session.

References GNUNET_ATS_Session::address, GNUNET_ATS_Session::bytes_in_queue, GNUNET_SYSERR, info, GNUNET_ATS_Session::msgs_in_queue, plugin, state, and GNUNET_ATS_Session::timeout.

Referenced by send_session_info_iter(), session_timeout(), unix_plugin_do_write(), unix_plugin_get_session(), unix_plugin_send(), and unix_plugin_session_disconnect().

Here is the caller graph for this function:

◆ unix_plugin_address_to_string()

static const char* unix_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
addrbinary address
addrlenlength of the addr
Returns
string representing the same address

Definition at line 367 of file plugin_transport_unix.c.

368 {
369  static char rbuf[1024];
370  struct UnixAddress *ua = (struct UnixAddress *) addr;
371  char *addrstr;
372  size_t addr_str_len;
373  unsigned int off;
374 
375  if ((NULL == addr) || (sizeof(struct UnixAddress) > addrlen))
376  {
377  GNUNET_break (0);
378  return NULL;
379  }
380  addrstr = (char *) &ua[1];
381  addr_str_len = ntohl (ua->addrlen);
382 
383  if (addr_str_len != addrlen - sizeof(struct UnixAddress))
384  {
385  GNUNET_break (0);
386  return NULL;
387  }
388  if ('\0' != addrstr[addr_str_len - 1])
389  {
390  GNUNET_break (0);
391  return NULL;
392  }
393  if (strlen (addrstr) + 1 != addr_str_len)
394  {
395  GNUNET_break (0);
396  return NULL;
397  }
398 
399  off = 0;
400  if ('\0' == addrstr[0])
401  off++;
402  memset (rbuf, 0, sizeof(rbuf));
403  GNUNET_snprintf (rbuf,
404  sizeof(rbuf) - 1,
405  "%s.%u.%s%.*s",
406  PLUGIN_NAME,
407  ntohl (ua->options),
408  (off == 1) ? "@" : "",
409  (int) (addr_str_len - off),
410  &addrstr[off]);
411  return rbuf;
412 }
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
#define PLUGIN_NAME
Name of the plugin.
Binary format for an UNIX Domain Socket address in GNUnet.
uint32_t options
Options to use for the address, in NBO.
uint32_t addrlen
Length of the address (path length), in NBO.

References UnixAddress::addrlen, GNUNET_break, GNUNET_snprintf(), UnixAddress::options, and PLUGIN_NAME.

Referenced by libgnunet_plugin_transport_unix_init(), unix_demultiplexer(), unix_plugin_address_pretty_printer(), unix_plugin_get_session(), unix_plugin_send(), and unix_plugin_session_disconnect().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ unix_plugin_session_disconnect()

static int unix_plugin_session_disconnect ( 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
clsclosure with the struct Plugin *
sessionsession to close down
Returns
GNUNET_OK on success

Definition at line 425 of file plugin_transport_unix.c.

426 {
427  struct Plugin *plugin = cls;
428  struct UNIXMessageWrapper *msgw;
429  struct UNIXMessageWrapper *next;
430 
432  "Disconnecting session for peer `%s' `%s'\n",
437  plugin->env->session_end (plugin->env->cls, session->address, session);
438  next = plugin->msg_head;
439  while (NULL != next)
440  {
441  msgw = next;
442  next = msgw->next;
443  if (msgw->session != session)
444  continue;
445  GNUNET_CONTAINER_DLL_remove (plugin->msg_head, plugin->msg_tail, msgw);
448  session->bytes_in_queue -= msgw->msgsize;
449  GNUNET_assert (plugin->bytes_in_queue >= msgw->msgsize);
450  plugin->bytes_in_queue -= msgw->msgsize;
451  if (NULL != msgw->cont)
452  msgw->cont (msgw->cont_cls,
453  &msgw->session->target,
455  msgw->payload,
456  0);
457  GNUNET_free (msgw->msg);
458  GNUNET_free (msgw);
459  }
462  &session->target,
463  session));
464  GNUNET_STATISTICS_set (plugin->env->stats,
465  "# UNIX sessions active",
467  plugin->session_map),
468  GNUNET_NO);
469  if (NULL != session->timeout_task)
470  {
472  session->timeout_task = NULL;
474  }
480  return GNUNET_OK;
481 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
enum GNUNET_GenericReturnValue 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.
#define GNUNET_HELLO_address_free(addr)
Free an address.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_DEBUG
#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:975
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
@ GNUNET_TRANSPORT_SS_DONE
Session is being torn down and about to disappear.
static const char * unix_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 LOG(kind,...)
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_PeerIdentity target
To whom are we talking to.
struct GNUNET_SCHEDULER_Task * timeout_task
Session timeout task.
size_t address_length
Number of bytes in address.
const void * address
Binary representation of the address (plugin-specific).
Handle for a plugin.
Definition: block.c:38
Information we track for a message awaiting transmission.
size_t payload
Number of bytes of payload encapsulated in msg.
struct UNIXMessageWrapper * next
We keep messages in a doubly linked list.
struct UNIXMessage * msg
The actual payload (allocated separately right now).
size_t msgsize
Number of bytes in msg.
GNUNET_TRANSPORT_TransmitContinuation cont
Function to call upon transmission.
void * cont_cls
Closure for cont.
struct GNUNET_ATS_Session * session
Session this message belongs to.

References GNUNET_HELLO_Address::address, GNUNET_ATS_Session::address, GNUNET_HELLO_Address::address_length, GNUNET_ATS_Session::bytes_in_queue, UNIXMessageWrapper::cont, UNIXMessageWrapper::cont_cls, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multipeermap_remove(), GNUNET_CONTAINER_multipeermap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_HELLO_address_free, GNUNET_i2s(), GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_set(), GNUNET_SYSERR, GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_SS_DONE, GNUNET_YES, LOG, UNIXMessageWrapper::msg, GNUNET_ATS_Session::msgs_in_queue, UNIXMessageWrapper::msgsize, UNIXMessageWrapper::next, notify_session_monitor(), UNIXMessageWrapper::payload, plugin, UNIXMessageWrapper::session, GNUNET_ATS_Session::target, GNUNET_ATS_Session::timeout, GNUNET_ATS_Session::timeout_task, and unix_plugin_address_to_string().

Referenced by get_session_delete_it(), libgnunet_plugin_transport_unix_init(), and session_timeout().

Here is the call graph for this function:
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 * to disconnect

Definition at line 490 of file plugin_transport_unix.c.

491 {
492  struct GNUNET_ATS_Session *session = cls;
493  struct GNUNET_TIME_Relative left;
494 
495  session->timeout_task = NULL;
497  if (0 != left.rel_value_us)
498  {
499  /* not actually our turn yet, but let's at least update
500  the monitor, it may think we're about to die ... */
501  notify_session_monitor (session->plugin,
502  session,
504  session->timeout_task =
506  return;
507  }
509  "Session %p was idle for %s, disconnecting\n",
510  session,
513  GNUNET_YES));
514  unix_plugin_session_disconnect (session->plugin, session);
515 }
#define GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT
After how long do we consider a connection to a peer dead if we don't receive messages from the peer?
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:1272
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:405
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:569
@ GNUNET_TRANSPORT_SS_UPDATE
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.
static int unix_plugin_session_disconnect(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...
Session handle for connections.
struct Plugin * plugin
Pointer to the global plugin struct.
Time for relative time used by GNUnet, in microseconds.

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, GNUNET_ATS_Session::timeout, GNUNET_ATS_Session::timeout_task, and unix_plugin_session_disconnect().

Referenced by unix_plugin_get_session().

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 session)
static

Increment session timeout due to activity.

We do not immediately notify the monitor here as that might generate excessive signalling.

Parameters
sessionsession for which the timeout should be rescheduled

Definition at line 526 of file plugin_transport_unix.c.

527 {
528  GNUNET_assert (NULL != session->timeout_task);
529  session->timeout =
531 }
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:316

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 unix_demultiplexer(), and unix_plugin_update_session_timeout().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ unix_address_to_sockaddr()

static struct sockaddr_un* unix_address_to_sockaddr ( const char *  unixpath,
socklen_t *  sock_len 
)
static

Convert unix path to a struct sockaddr_un *

Parameters
unixpathpath to convert
[out]sock_lenset to the length of the address
Returns
converted unix path

Definition at line 542 of file plugin_transport_unix.c.

543 {
544  struct sockaddr_un *un;
545  size_t slen;
546 
547  GNUNET_assert (0 < strlen (unixpath)); /* sanity check */
548  un = GNUNET_new (struct sockaddr_un);
549  un->sun_family = AF_UNIX;
550  slen = strlen (unixpath);
551  if (slen >= sizeof(un->sun_path))
552  slen = sizeof(un->sun_path) - 1;
553  GNUNET_memcpy (un->sun_path, unixpath, slen);
554  un->sun_path[slen] = '\0';
555  slen = sizeof(struct sockaddr_un);
556 #if HAVE_SOCKADDR_UN_SUN_LEN
557  un->sun_len = (u_char) slen;
558 #endif
559  (*sock_len) = slen;
560  return un;
561 }
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_new(type)
Allocate a struct or union of the given type.

References GNUNET_assert, GNUNET_memcpy, and GNUNET_new.

Referenced by unix_plugin_get_network(), and unix_transport_server_start().

Here is the caller graph for this function:

◆ lookup_session_it()

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

Function called to find a session by address.

Parameters
clsthe struct LookupCtx *
keypeer we are looking for (unused)
valuea session
Returns
GNUNET_YES if not found (continue looking), GNUNET_NO on success

Definition at line 590 of file plugin_transport_unix.c.

593 {
594  struct LookupCtx *lctx = cls;
595  struct GNUNET_ATS_Session *session = value;
596 
597  if (0 == GNUNET_HELLO_address_cmp (lctx->address, session->address))
598  {
599  lctx->res = session;
600  return GNUNET_NO;
601  }
602  return GNUNET_YES;
603 }
static char * value
Value of the record to add/remove.
int GNUNET_HELLO_address_cmp(const struct GNUNET_HELLO_Address *a1, const struct GNUNET_HELLO_Address *a2)
Compare two addresses.
Definition: address.c:112
Closure to lookup_queue_it().
const struct GNUNET_HELLO_Address * address
Address we are looking for.
struct Queue * res
Location to store the queue, if found.

References GNUNET_ATS_Session::address, LookupCtx::address, GNUNET_HELLO_address_cmp(), GNUNET_NO, GNUNET_YES, LookupCtx::res, and value.

Referenced by lookup_session().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ lookup_session()

static struct GNUNET_ATS_Session* lookup_session ( struct Plugin plugin,
const struct GNUNET_HELLO_Address address 
)
static

Find an existing session by address.

Parameters
pluginthe plugin
addressthe address to find
Returns
NULL if session was not found

Definition at line 614 of file plugin_transport_unix.c.

616 {
617  struct LookupCtx lctx;
618 
619  lctx.address = address;
620  lctx.res = NULL;
622  &address->peer,
624  &lctx);
625  return lctx.res;
626 }
static char * address
GNS address for this phone.
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.
static int lookup_session_it(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Function called to find a session by address.

References address, LookupCtx::address, GNUNET_CONTAINER_multipeermap_get_multiple(), lookup_session_it(), plugin, and LookupCtx::res.

Referenced by unix_demultiplexer(), and unix_plugin_get_session().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ unix_plugin_query_keepalive_factor()

static unsigned int unix_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 638 of file plugin_transport_unix.c.

639 {
640  return 3;
641 }

Referenced by libgnunet_plugin_transport_unix_init().

Here is the caller graph for this function:

◆ unix_real_send()

static ssize_t unix_real_send ( void *  cls,
struct GNUNET_NETWORK_Handle send_handle,
const struct GNUNET_PeerIdentity target,
const char *  msgbuf,
size_t  msgbuf_size,
unsigned int  priority,
struct GNUNET_TIME_Absolute  timeout,
const struct UnixAddress addr,
size_t  addrlen,
size_t  payload,
GNUNET_TRANSPORT_TransmitContinuation  cont,
void *  cont_cls 
)
static

Actually send out the message, assume we've got the address and send_handle squared away!

Parameters
clsclosure
send_handlewhich handle to send message on
targetwho should receive this message (ignored by UNIX)
msgbufone or more GNUNET_MessageHeader(s) strung together
msgbuf_sizethe size of the msgbuf to send
priorityhow important is the message (ignored by UNIX)
timeoutwhen should we time out (give up) if we can not transmit?
addrthe addr to send the message to, needs to be a sockaddr for us
addrlenthe len of addr
payloadbytes payload to send
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...)
cont_clsclosure for cont
Returns
on success the number of bytes written, RETRY for retry, -1 on errors

Definition at line 666 of file plugin_transport_unix.c.

678 {
679  struct Plugin *plugin = cls;
680  ssize_t sent;
681  struct sockaddr_un *un;
682  socklen_t un_len;
683  const char *unixpath;
684 
685  if (NULL == send_handle)
686  {
687  GNUNET_break (0); /* We do not have a send handle */
688  return GNUNET_SYSERR;
689  }
690  if ((NULL == addr) || (0 == addrlen))
691  {
692  GNUNET_break (0); /* Can never send if we don't have an address */
693  return GNUNET_SYSERR;
694  }
695 
696  /* Prepare address */
697  unixpath = (const char *) &addr[1];
698  if (NULL == (un = unix_address_to_sockaddr (unixpath, &un_len)))
699  {
700  GNUNET_break (0);
701  return -1;
702  }
703 
704  if ((GNUNET_YES == plugin->is_abstract) &&
705  (0 != (UNIX_OPTIONS_USE_ABSTRACT_SOCKETS & ntohl (addr->options))))
706  {
707  un->sun_path[0] = '\0';
708  }
709 resend:
710  /* Send the data */
711  sent = GNUNET_NETWORK_socket_sendto (send_handle,
712  msgbuf,
713  msgbuf_size,
714  (const struct sockaddr *) un,
715  un_len);
716  if (GNUNET_SYSERR == sent)
717  {
718  if ((EAGAIN == errno) || (ENOBUFS == errno))
719  {
720  GNUNET_free (un);
721  return RETRY; /* We have to retry later */
722  }
723  if (EMSGSIZE == errno)
724  {
725  socklen_t size = 0;
726  socklen_t len = sizeof(size);
727 
729  send_handle,
730  SOL_SOCKET,
731  SO_SNDBUF,
732  &size,
733  &len);
734  if (size < msgbuf_size)
735  {
737  "Trying to increase socket buffer size from %u to %u for message size %u\n",
738  (unsigned int) size,
739  (unsigned int) ((msgbuf_size / 1000) + 2) * 1000,
740  (unsigned int) msgbuf_size);
741  size = ((msgbuf_size / 1000) + 2) * 1000;
742  if (GNUNET_OK ==
744  send_handle,
745  SOL_SOCKET,
746  SO_SNDBUF,
747  &size,
748  sizeof(size)))
749  goto resend; /* Increased buffer size, retry sending */
750  else
751  {
752  /* Could not increase buffer size: error, no retry */
754  GNUNET_free (un);
755  return GNUNET_SYSERR;
756  }
757  }
758  else
759  {
760  /* Buffer is bigger than message: error, no retry
761  * This should never happen!*/
762  GNUNET_break (0);
763  GNUNET_free (un);
764  return GNUNET_SYSERR;
765  }
766  }
767  }
768 
770  "UNIX transmitted %u-byte message to %s (%d: %s)\n",
771  (unsigned int) msgbuf_size,
772  GNUNET_a2s ((const struct sockaddr *) un, un_len),
773  (int) sent,
774  (sent < 0) ? strerror (errno) : "ok");
775  GNUNET_free (un);
776  return sent;
777 }
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
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).
@ GNUNET_ERROR_TYPE_ERROR
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_getsockopt(const struct GNUNET_NETWORK_Handle *desc, int level, int optname, void *optval, socklen_t *optlen)
Get socket options.
Definition: network.c:626
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:805
ssize_t GNUNET_NETWORK_socket_sendto(const struct GNUNET_NETWORK_Handle *desc, const void *message, size_t length, const struct sockaddr *dest_addr, socklen_t dest_len)
Send data to a particular destination (always non-blocking).
Definition: network.c:771
static unsigned int size
Size of the "table".
Definition: peer.c:68
static struct sockaddr_un * unix_address_to_sockaddr(const char *unixpath, socklen_t *sock_len)
Convert unix path to a struct sockaddr_un *
#define RETRY
Return code we give on 'send' if we failed to send right now but it makes sense to retry later.
handle to a socket
Definition: network.c:53

Referenced by unix_plugin_do_write().

Here is the caller graph for this function:

◆ unix_plugin_get_network()

static enum GNUNET_NetworkType unix_plugin_get_network ( void *  cls,
struct GNUNET_ATS_Session session 
)
static

Function obtain the network type for a session.

Parameters
clsclosure ('struct Plugin*')
sessionthe session
Returns
the network type in HBO or GNUNET_SYSERR

Definition at line 666 of file plugin_transport_unix.c.

789 {
790  GNUNET_assert (NULL != session);
791  return GNUNET_NT_LOOPBACK;
792 }
@ GNUNET_NT_LOOPBACK
Loopback (same host).
Definition: gnunet_nt_lib.h:48

References GNUNET_a2s(), GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log_strerror, GNUNET_NETWORK_socket_getsockopt(), GNUNET_NETWORK_socket_sendto(), GNUNET_NETWORK_socket_setsockopt(), GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, len, LOG, UnixAddress::options, plugin, RETRY, size, unix_address_to_sockaddr(), and UNIX_OPTIONS_USE_ABSTRACT_SOCKETS.

Referenced by libgnunet_plugin_transport_unix_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ unix_plugin_get_network_for_address()

static enum GNUNET_NetworkType unix_plugin_get_network_for_address ( void *  cls,
const struct GNUNET_HELLO_Address address 
)
static

Function obtain the network type for a session.

Parameters
clsclosure (struct Plugin *)
addressthe address
Returns
the network type

Definition at line 666 of file plugin_transport_unix.c.

805 {
806  return GNUNET_NT_LOOPBACK;
807 }

Referenced by libgnunet_plugin_transport_unix_init().

Here is the caller graph for this function:

◆ unix_plugin_get_session()

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

Creates a new outbound session the transport service will use to send data to the peer.

Parameters
clsthe plugin
addressthe address
Returns
the session or NULL of max connections exceeded

Definition at line 819 of file plugin_transport_unix.c.

820 {
821  struct Plugin *plugin = cls;
822  struct GNUNET_ATS_Session *session;
823  struct UnixAddress *ua;
824  char *addrstr;
825  uint32_t addr_str_len;
826  uint32_t addr_option;
827 
828  ua = (struct UnixAddress *) address->address;
829  if ((NULL == address->address) || (0 == address->address_length) ||
830  (sizeof(struct UnixAddress) > address->address_length))
831  {
832  GNUNET_break (0);
833  return NULL;
834  }
835  addrstr = (char *) &ua[1];
836  addr_str_len = ntohl (ua->addrlen);
837  addr_option = ntohl (ua->options);
838 
839  if ((0 != (UNIX_OPTIONS_USE_ABSTRACT_SOCKETS & addr_option)) &&
840  (GNUNET_NO == plugin->is_abstract))
841  {
842  return NULL;
843  }
844 
845  if (addr_str_len != address->address_length - sizeof(struct UnixAddress))
846  {
847  return NULL; /* This can be a legacy address */
848  }
849 
850  if ('\0' != addrstr[addr_str_len - 1])
851  {
852  GNUNET_break (0);
853  return NULL;
854  }
855  if (strlen (addrstr) + 1 != addr_str_len)
856  {
857  GNUNET_break (0);
858  return NULL;
859  }
860 
861  /* Check if a session for this address already exists */
862  if (NULL != (session = lookup_session (plugin, address)))
863  {
865  "Found existing session %p for address `%s'\n",
866  session,
868  address->address,
869  address->address_length));
870  return session;
871  }
872 
873  /* create a new session */
874  session = GNUNET_new (struct GNUNET_ATS_Session);
875  session->target = address->peer;
877  session->plugin = plugin;
878  session->timeout =
880  session->timeout_task =
883  session);
885  "Creating a new session %p for address `%s'\n",
886  session,
888  address->address,
889  address->address_length));
891  plugin->session_map,
892  &address->peer,
893  session,
895  GNUNET_STATISTICS_set (plugin->env->stats,
896  "# UNIX sessions active",
898  plugin->session_map),
899  GNUNET_NO);
902  return session;
903 }
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.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
struct GNUNET_HELLO_Address * GNUNET_HELLO_address_copy(const struct GNUNET_HELLO_Address *address)
Copy an address struct.
Definition: address.c:99
@ GNUNET_TRANSPORT_SS_INIT
The session was created (first call for each session object).
@ GNUNET_TRANSPORT_SS_UP
Session is fully UP.
static struct GNUNET_ATS_Session * lookup_session(struct Plugin *plugin, const struct GNUNET_HELLO_Address *address)
Find an existing session by address.

References address, GNUNET_ATS_Session::address, UnixAddress::addrlen, GNUNET_break, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE, GNUNET_CONTAINER_multipeermap_put(), GNUNET_CONTAINER_multipeermap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_HELLO_address_copy(), GNUNET_new, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_STATISTICS_set(), GNUNET_TIME_relative_to_absolute(), GNUNET_TRANSPORT_SS_INIT, GNUNET_TRANSPORT_SS_UP, LOG, lookup_session(), notify_session_monitor(), UnixAddress::options, plugin, GNUNET_ATS_Session::plugin, session_timeout(), GNUNET_ATS_Session::target, GNUNET_ATS_Session::timeout, GNUNET_ATS_Session::timeout_task, UNIX_OPTIONS_USE_ABSTRACT_SOCKETS, and unix_plugin_address_to_string().

Referenced by libgnunet_plugin_transport_unix_init(), and unix_demultiplexer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ unix_plugin_update_session_timeout()

static void unix_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 with the struct Plugin *
peerwhich peer was the session for
sessionwhich session is being updated

Definition at line 916 of file plugin_transport_unix.c.

919 {
920  struct Plugin *plugin = cls;
921 
922  if (GNUNET_OK !=
924  &session->target,
925  session))
926  {
927  GNUNET_break (0);
928  return;
929  }
930  reschedule_session_timeout (session);
931 }
enum GNUNET_GenericReturnValue 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 reschedule_session_timeout(struct GNUNET_ATS_Session *session)
Increment session timeout due to activity.

References GNUNET_break, GNUNET_CONTAINER_multipeermap_contains_value(), GNUNET_OK, plugin, reschedule_session_timeout(), and GNUNET_ATS_Session::target.

Referenced by libgnunet_plugin_transport_unix_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ unix_demultiplexer()

static void unix_demultiplexer ( struct Plugin plugin,
struct GNUNET_PeerIdentity sender,
const struct GNUNET_MessageHeader currhdr,
const struct UnixAddress ua,
size_t  ua_len 
)
static

Demultiplexer for UNIX messages.

Parameters
pluginthe main plugin for this transport
senderfrom which peer the message was received
currhdrpointer to the header of the message
uaaddress to look for
ua_lenlength of the address ua

Definition at line 944 of file plugin_transport_unix.c.

949 {
950  struct GNUNET_ATS_Session *session;
952 
953  GNUNET_assert (ua_len >= sizeof(struct UnixAddress));
955  "Received message from %s\n",
956  unix_plugin_address_to_string (NULL, ua, ua_len));
957  GNUNET_STATISTICS_update (plugin->env->stats,
958  "# bytes received via UNIX",
959  ntohs (currhdr->size),
960  GNUNET_NO);
961 
962  /* Look for existing session */
964  sender,
965  PLUGIN_NAME,
966  ua,
967  ua_len,
968  GNUNET_HELLO_ADDRESS_INFO_NONE); /* UNIX does not have "inbound" sessions */
969  session = lookup_session (plugin, address);
970  if (NULL == session)
971  {
973  /* Notify transport and ATS about new inbound session */
974  plugin->env->session_start (NULL,
975  session->address,
976  session,
978  }
979  else
980  {
981  reschedule_session_timeout (session);
982  }
984  plugin->env->receive (plugin->env->cls, session->address, session, currhdr);
985 }
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:63
@ GNUNET_HELLO_ADDRESS_INFO_NONE
No additional information.
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_Session * unix_plugin_get_session(void *cls, const struct GNUNET_HELLO_Address *address)
Creates a new outbound session the transport service will use to send data to the peer.
An address for communicating with a peer.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.

References address, GNUNET_ATS_Session::address, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_HELLO_address_allocate(), GNUNET_HELLO_address_free, GNUNET_HELLO_ADDRESS_INFO_NONE, GNUNET_NO, GNUNET_NT_LOOPBACK, GNUNET_STATISTICS_update(), LOG, lookup_session(), plugin, PLUGIN_NAME, reschedule_session_timeout(), GNUNET_MessageHeader::size, unix_plugin_address_to_string(), and unix_plugin_get_session().

Referenced by unix_plugin_do_read().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ unix_plugin_do_read()

static void unix_plugin_do_read ( struct Plugin plugin)
static

Read from UNIX domain socket (it is ready).

Parameters
pluginthe plugin

Definition at line 994 of file plugin_transport_unix.c.

995 {
996  char buf[65536] GNUNET_ALIGN;
997  struct UnixAddress *ua;
998  struct UNIXMessage *msg;
999  struct GNUNET_PeerIdentity sender;
1000  struct sockaddr_un un;
1001  socklen_t addrlen;
1002  ssize_t ret;
1003  int offset;
1004  int tsize;
1005  int is_abstract;
1006  char *msgbuf;
1007  const struct GNUNET_MessageHeader *currhdr;
1008  uint16_t csize;
1009  size_t ua_len;
1010 
1011  addrlen = sizeof(un);
1012  memset (&un, 0, sizeof(un));
1013  ret = GNUNET_NETWORK_socket_recvfrom (plugin->unix_sock.desc,
1014  buf,
1015  sizeof(buf),
1016  (struct sockaddr *) &un,
1017  &addrlen);
1018  if ((GNUNET_SYSERR == ret) && ((errno == EAGAIN) || (errno == ENOBUFS)))
1019  return;
1020  if (GNUNET_SYSERR == ret)
1021  {
1023  return;
1024  }
1025  else
1026  {
1028  "Read %d bytes from socket %s\n",
1029  (int) ret,
1030  un.sun_path);
1031  }
1032 
1033  GNUNET_assert (AF_UNIX == (un.sun_family));
1034  is_abstract = GNUNET_NO;
1035  if ('\0' == un.sun_path[0])
1036  {
1037  un.sun_path[0] = '@';
1038  is_abstract = GNUNET_YES;
1039  }
1040 
1041  ua_len = sizeof(struct UnixAddress) + strlen (un.sun_path) + 1;
1042  ua = GNUNET_malloc (ua_len);
1043  ua->addrlen = htonl (strlen (&un.sun_path[0]) + 1);
1044  GNUNET_memcpy (&ua[1], &un.sun_path[0], strlen (un.sun_path) + 1);
1045  if (is_abstract)
1046  ua->options = htonl (UNIX_OPTIONS_USE_ABSTRACT_SOCKETS);
1047  else
1048  ua->options = htonl (UNIX_OPTIONS_NONE);
1049 
1050  msg = (struct UNIXMessage *) buf;
1051  csize = ntohs (msg->header.size);
1052  if ((csize < sizeof(struct UNIXMessage)) || (csize > ret))
1053  {
1054  GNUNET_break_op (0);
1055  GNUNET_free (ua);
1056  return;
1057  }
1058  msgbuf = (char *) &msg[1];
1059  GNUNET_memcpy (&sender, &msg->sender, sizeof(struct GNUNET_PeerIdentity));
1060  offset = 0;
1061  tsize = csize - sizeof(struct UNIXMessage);
1062  while (offset + sizeof(struct GNUNET_MessageHeader) <= tsize)
1063  {
1064  currhdr = (struct GNUNET_MessageHeader *) &msgbuf[offset];
1065  csize = ntohs (currhdr->size);
1066  if ((csize < sizeof(struct GNUNET_MessageHeader)) ||
1067  (csize > tsize - offset))
1068  {
1069  GNUNET_break_op (0);
1070  break;
1071  }
1072  unix_demultiplexer (plugin, &sender, currhdr, ua, ua_len);
1073  offset += csize;
1074  }
1075  GNUNET_free (ua);
1076 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static char buf[2048]
static unsigned int csize
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
@ GNUNET_ERROR_TYPE_WARNING
#define GNUNET_malloc(size)
Wrapper around malloc.
ssize_t GNUNET_NETWORK_socket_recvfrom(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length, struct sockaddr *src_addr, socklen_t *addrlen)
Read data from a socket (always non-blocking).
Definition: network.c:687
static void unix_demultiplexer(struct Plugin *plugin, struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *currhdr, const struct UnixAddress *ua, size_t ua_len)
Demultiplexer for UNIX messages.
Header for all communications.
The identity of the host (wraps the signing key of the peer).
UNIX Message-Packet header.
struct GNUNET_PeerIdentity sender
What is the identity of the sender (GNUNET_hash of public key)

References UnixAddress::addrlen, buf, csize, GNUNET_ALIGN, GNUNET_assert, GNUNET_break_op, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log_strerror, GNUNET_malloc, GNUNET_memcpy, GNUNET_NETWORK_socket_recvfrom(), GNUNET_NO, GNUNET_SYSERR, GNUNET_YES, LOG, msg, UnixAddress::options, plugin, ret, UNIXMessage::sender, GNUNET_MessageHeader::size, unix_demultiplexer(), UNIX_OPTIONS_NONE, and UNIX_OPTIONS_USE_ABSTRACT_SOCKETS.

Referenced by unix_plugin_select_read().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ unix_plugin_do_write()

static void unix_plugin_do_write ( struct Plugin plugin)
static

Write to UNIX domain socket (it is ready).

Parameters
pluginhandle to the plugin

Definition at line 1085 of file plugin_transport_unix.c.

1086 {
1087  ssize_t sent = 0;
1088  struct UNIXMessageWrapper *msgw;
1089  struct GNUNET_ATS_Session *session;
1090  int did_delete;
1091 
1092  session = NULL;
1093  did_delete = GNUNET_NO;
1094  while (NULL != (msgw = plugin->msg_head))
1095  {
1097  break; /* Message is ready for sending */
1098  /* Message has a timeout */
1099  did_delete = GNUNET_YES;
1101  "Timeout for message with %u bytes \n",
1102  (unsigned int) msgw->msgsize);
1103  GNUNET_CONTAINER_DLL_remove (plugin->msg_head, plugin->msg_tail, msgw);
1104  session = msgw->session;
1105  session->msgs_in_queue--;
1106  GNUNET_assert (session->bytes_in_queue >= msgw->msgsize);
1107  session->bytes_in_queue -= msgw->msgsize;
1108  GNUNET_assert (plugin->bytes_in_queue >= msgw->msgsize);
1109  plugin->bytes_in_queue -= msgw->msgsize;
1110  GNUNET_STATISTICS_set (plugin->env->stats,
1111  "# bytes currently in UNIX buffers",
1112  plugin->bytes_in_queue,
1113  GNUNET_NO);
1114  GNUNET_STATISTICS_update (plugin->env->stats,
1115  "# UNIX bytes discarded",
1116  msgw->msgsize,
1117  GNUNET_NO);
1118  if (NULL != msgw->cont)
1119  msgw->cont (msgw->cont_cls,
1120  &msgw->session->target,
1121  GNUNET_SYSERR,
1122  msgw->payload,
1123  0);
1124  GNUNET_free (msgw->msg);
1125  GNUNET_free (msgw);
1126  }
1127  if (NULL == msgw)
1128  {
1129  if (GNUNET_YES == did_delete)
1131  return; /* Nothing to send at the moment */
1132  }
1133  session = msgw->session;
1134  sent = unix_real_send (plugin,
1135  plugin->unix_sock.desc,
1136  &session->target,
1137  (const char *) msgw->msg,
1138  msgw->msgsize,
1139  msgw->priority,
1140  msgw->timeout,
1141  msgw->session->address->address,
1142  msgw->session->address->address_length,
1143  msgw->payload,
1144  msgw->cont,
1145  msgw->cont_cls);
1146  if (RETRY == sent)
1147  {
1148  GNUNET_STATISTICS_update (plugin->env->stats,
1149  "# UNIX retry attempts",
1150  1,
1151  GNUNET_NO);
1153  return;
1154  }
1155  GNUNET_CONTAINER_DLL_remove (plugin->msg_head, plugin->msg_tail, msgw);
1156  session->msgs_in_queue--;
1157  GNUNET_assert (session->bytes_in_queue >= msgw->msgsize);
1158  session->bytes_in_queue -= msgw->msgsize;
1159  GNUNET_assert (plugin->bytes_in_queue >= msgw->msgsize);
1160  plugin->bytes_in_queue -= msgw->msgsize;
1161  GNUNET_STATISTICS_set (plugin->env->stats,
1162  "# bytes currently in UNIX buffers",
1163  plugin->bytes_in_queue,
1164  GNUNET_NO);
1166  if (GNUNET_SYSERR == sent)
1167  {
1168  /* failed and no retry */
1169  if (NULL != msgw->cont)
1170  msgw->cont (msgw->cont_cls,
1171  &msgw->session->target,
1172  GNUNET_SYSERR,
1173  msgw->payload,
1174  0);
1175  GNUNET_STATISTICS_update (plugin->env->stats,
1176  "# UNIX bytes discarded",
1177  msgw->msgsize,
1178  GNUNET_NO);
1179  GNUNET_free (msgw->msg);
1180  GNUNET_free (msgw);
1181  return;
1182  }
1183  /* successfully sent bytes */
1184  GNUNET_break (sent > 0);
1185  GNUNET_STATISTICS_update (plugin->env->stats,
1186  "# bytes transmitted via UNIX",
1187  msgw->msgsize,
1188  GNUNET_NO);
1189  if (NULL != msgw->cont)
1190  msgw->cont (msgw->cont_cls,
1191  &msgw->session->target,
1192  GNUNET_OK,
1193  msgw->payload,
1194  msgw->msgsize);
1195  GNUNET_free (msgw->msg);
1196  GNUNET_free (msgw);
1197 }
static ssize_t unix_real_send(void *cls, struct GNUNET_NETWORK_Handle *send_handle, const struct GNUNET_PeerIdentity *target, const char *msgbuf, size_t msgbuf_size, unsigned int priority, struct GNUNET_TIME_Absolute timeout, const struct UnixAddress *addr, size_t addrlen, size_t payload, GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
Actually send out the message, assume we've got the address and send_handle squared away!
uint64_t rel_value_us
The actual value.
struct GNUNET_TIME_Absolute timeout
Timeout for this message.
unsigned int priority
Priority of the message (ignored, just dragged along in UNIX).

References GNUNET_HELLO_Address::address, GNUNET_ATS_Session::address, GNUNET_HELLO_Address::address_length, GNUNET_ATS_Session::bytes_in_queue, UNIXMessageWrapper::cont, UNIXMessageWrapper::cont_cls, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_set(), GNUNET_STATISTICS_update(), GNUNET_SYSERR, GNUNET_TIME_absolute_get_remaining(), GNUNET_TRANSPORT_SS_UPDATE, GNUNET_YES, LOG, UNIXMessageWrapper::msg, GNUNET_ATS_Session::msgs_in_queue, UNIXMessageWrapper::msgsize, notify_session_monitor(), UNIXMessageWrapper::payload, plugin, UNIXMessageWrapper::priority, GNUNET_TIME_Relative::rel_value_us, RETRY, UNIXMessageWrapper::session, GNUNET_ATS_Session::target, UNIXMessageWrapper::timeout, and unix_real_send().

Referenced by unix_plugin_select_write().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ unix_plugin_select_read()

static void unix_plugin_select_read ( void *  cls)
static

We have been notified that our socket has something to read.

Then reschedule this function to be called again once more is available.

Parameters
clsthe plugin handle

Definition at line 1207 of file plugin_transport_unix.c.

1208 {
1209  struct Plugin *plugin = cls;
1210  const struct GNUNET_SCHEDULER_TaskContext *tc;
1211 
1212  plugin->read_task = NULL;
1216  plugin->read_task =
1218  plugin->unix_sock.desc,
1220  plugin);
1221 }
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c:1506
const struct GNUNET_SCHEDULER_TaskContext * GNUNET_SCHEDULER_get_task_context(void)
Obtain the reasoning why the current task was started.
Definition: scheduler.c:752
@ GNUNET_SCHEDULER_REASON_READ_READY
The reading socket is ready.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
static void unix_plugin_select_read(void *cls)
We have been notified that our socket has something to read.
static void unix_plugin_do_read(struct Plugin *plugin)
Read from UNIX domain socket (it is ready).
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:431
Context information passed to each scheduler task.
enum GNUNET_SCHEDULER_Reason reason
Reason why the task is run now.

References GNUNET_SCHEDULER_add_read_net(), GNUNET_SCHEDULER_get_task_context(), GNUNET_SCHEDULER_REASON_READ_READY, GNUNET_TIME_UNIT_FOREVER_REL, plugin, GNUNET_SCHEDULER_TaskContext::reason, tc, and unix_plugin_do_read().

Referenced by unix_transport_server_start().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ unix_plugin_select_write()

static void unix_plugin_select_write ( void *  cls)
static

We have been notified that our socket is ready to write.

Then reschedule this function to be called again once more is available.

Parameters
clsthe plugin handle

Definition at line 1231 of file plugin_transport_unix.c.

1232 {
1233  struct Plugin *plugin = cls;
1234  const struct GNUNET_SCHEDULER_TaskContext *tc;
1235 
1236  plugin->write_task = NULL;
1240  if (NULL == plugin->msg_head)
1241  return; /* write queue empty */
1242  plugin->write_task =
1244  plugin->unix_sock.desc,
1246  plugin);
1247 }
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_write_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *wfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c:1577
@ GNUNET_SCHEDULER_REASON_WRITE_READY
The writing socket is ready.
static void unix_plugin_select_write(void *cls)
We have been notified that our socket is ready to write.
static void unix_plugin_do_write(struct Plugin *plugin)
Write to UNIX domain socket (it is ready).

References GNUNET_SCHEDULER_add_write_net(), GNUNET_SCHEDULER_get_task_context(), GNUNET_SCHEDULER_REASON_WRITE_READY, GNUNET_TIME_UNIT_FOREVER_REL, plugin, GNUNET_SCHEDULER_TaskContext::reason, tc, and unix_plugin_do_write().

Referenced by unix_plugin_send().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ unix_plugin_send()

static ssize_t unix_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 1278 of file plugin_transport_unix.c.

1286 {
1287  struct Plugin *plugin = cls;
1288  struct UNIXMessageWrapper *wrapper;
1289  struct UNIXMessage *message;
1290  int ssize;
1291 
1292  if (GNUNET_OK !=
1294  &session->target,
1295  session))
1296  {
1298  "Invalid session for peer `%s' `%s'\n",
1299  GNUNET_i2s (&session->target),
1301  session->address->address,
1302  session->address->address_length));
1303  GNUNET_break (0);
1304  return GNUNET_SYSERR;
1305  }
1307  "Sending %lu bytes with session for peer `%s' `%s'\n",
1308  (unsigned long) msgbuf_size,
1309  GNUNET_i2s (&session->target),
1311  session->address->address,
1312  session->address->address_length));
1313  ssize = sizeof(struct UNIXMessage) + msgbuf_size;
1314  message = GNUNET_malloc (sizeof(struct UNIXMessage) + msgbuf_size);
1315  message->header.size = htons (ssize);
1316  message->header.type = htons (0);
1317  GNUNET_memcpy (&message->sender,
1318  plugin->env->my_identity,
1319  sizeof(struct GNUNET_PeerIdentity));
1320  GNUNET_memcpy (&message[1], msgbuf, msgbuf_size);
1321  wrapper = GNUNET_new (struct UNIXMessageWrapper);
1322  wrapper->msg = message;
1323  wrapper->msgsize = ssize;
1324  wrapper->payload = msgbuf_size;
1325  wrapper->priority = priority;
1327  wrapper->cont = cont;
1328  wrapper->cont_cls = cont_cls;
1329  wrapper->session = session;
1331  plugin->msg_tail,
1332  wrapper);
1333  plugin->bytes_in_queue += ssize;
1334  session->bytes_in_queue += ssize;
1335  session->msgs_in_queue++;
1336  GNUNET_STATISTICS_set (plugin->env->stats,
1337  "# bytes currently in UNIX buffers",
1338  plugin->bytes_in_queue,
1339  GNUNET_NO);
1341  if (NULL == plugin->write_task)
1342  plugin->write_task =
1344  plugin->unix_sock.desc,
1346  plugin);
1347  return ssize;
1348 }
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_add(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Relative duration)
Add a given relative duration to the given start time.
Definition: time.c:450

References GNUNET_HELLO_Address::address, GNUNET_ATS_Session::address, GNUNET_HELLO_Address::address_length, GNUNET_ATS_Session::bytes_in_queue, UNIXMessageWrapper::cont, UNIXMessageWrapper::cont_cls, GNUNET_break, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_CONTAINER_multipeermap_contains_value(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_i2s(), GNUNET_malloc, GNUNET_memcpy, GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_write_net(), GNUNET_STATISTICS_set(), GNUNET_SYSERR, GNUNET_TIME_absolute_add(), GNUNET_TIME_absolute_get(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_TRANSPORT_SS_UPDATE, UNIXMessage::header, LOG, UNIXMessageWrapper::msg, GNUNET_ATS_Session::msgs_in_queue, UNIXMessageWrapper::msgsize, notify_session_monitor(), UNIXMessageWrapper::payload, plugin, UNIXMessageWrapper::priority, UNIXMessage::sender, UNIXMessageWrapper::session, GNUNET_MessageHeader::size, GNUNET_ATS_Session::target, UNIXMessageWrapper::timeout, GNUNET_MessageHeader::type, unix_plugin_address_to_string(), and unix_plugin_select_write().

Referenced by libgnunet_plugin_transport_unix_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ unix_transport_server_start()

static int unix_transport_server_start ( void *  cls)
static

Create a slew of UNIX sockets.

If possible, use IPv6 and IPv4.

Parameters
clsclosure for server start, should be a struct Plugin *
Returns
number of sockets created or GNUNET_SYSERR on error

Definition at line 1358 of file plugin_transport_unix.c.

1359 {
1360  struct Plugin *plugin = cls;
1361  struct sockaddr_un *un;
1362  socklen_t un_len;
1363 
1364  un = unix_address_to_sockaddr (plugin->unix_socket_path, &un_len);
1365  if (GNUNET_YES == plugin->is_abstract)
1366  {
1367  plugin->unix_socket_path[0] = '@';
1368  un->sun_path[0] = '\0';
1369  }
1370  plugin->unix_sock.desc =
1371  GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_DGRAM, 0);
1372  if (NULL == plugin->unix_sock.desc)
1373  {
1375  GNUNET_free (un);
1376  return GNUNET_SYSERR;
1377  }
1378  if ('\0' != un->sun_path[0])
1379  {
1380  if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (un->sun_path))
1381  {
1383  _ ("Cannot create path to `%s'\n"),
1384  un->sun_path);
1385  GNUNET_NETWORK_socket_close (plugin->unix_sock.desc);
1386  plugin->unix_sock.desc = NULL;
1387  GNUNET_free (un);
1388  return GNUNET_SYSERR;
1389  }
1390  }
1391  if (GNUNET_OK != GNUNET_NETWORK_socket_bind (plugin->unix_sock.desc,
1392  (const struct sockaddr *) un,
1393  un_len))
1394  {
1396  LOG (GNUNET_ERROR_TYPE_ERROR, _ ("Cannot bind to `%s'\n"), un->sun_path);
1397  GNUNET_NETWORK_socket_close (plugin->unix_sock.desc);
1398  plugin->unix_sock.desc = NULL;
1399  GNUNET_free (un);
1400  return GNUNET_SYSERR;
1401  }
1402  LOG (GNUNET_ERROR_TYPE_DEBUG, "Bound to `%s'\n", plugin->unix_socket_path);
1403  plugin->read_task =
1405  plugin->unix_sock.desc,
1407  plugin);
1408  GNUNET_free (un);
1409  return 1;
1410 }
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:582
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:508
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:832
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition: network.c:439
#define _(String)
GNU gettext support macro.
Definition: platform.h:177

References _, GNUNET_DISK_directory_create_for_file(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log_strerror, GNUNET_NETWORK_socket_bind(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_create(), GNUNET_OK, GNUNET_SCHEDULER_add_read_net(), GNUNET_SYSERR, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, LOG, plugin, unix_address_to_sockaddr(), and unix_plugin_select_read().

Referenced by libgnunet_plugin_transport_unix_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ unix_plugin_check_address()

static int unix_plugin_check_address ( void *  cls,
const void *  addr,
size_t  addrlen 
)
static

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).

Naturally, if absolutely necessary, plugins can be a bit conservative in their answer, but in general plugins should make sure that the address does not redirect traffic to a 3rd party that might try to man-in-the-middle our traffic.

Parameters
clsclosure, should be our handle to the Plugin
addrpointer to the address
addrlenlength of addr
Returns
GNUNET_OK if this is a plausible address for this peer and transport, GNUNET_SYSERR if not

Definition at line 1430 of file plugin_transport_unix.c.

1431 {
1432  struct Plugin *plugin = cls;
1433  const struct UnixAddress *ua = addr;
1434  char *addrstr;
1435  size_t addr_str_len;
1436 
1437  if ((NULL == addr) || (0 == addrlen) ||
1438  (sizeof(struct UnixAddress) > addrlen))
1439  {
1440  GNUNET_break (0);
1441  return GNUNET_SYSERR;
1442  }
1443  addrstr = (char *) &ua[1];
1444  addr_str_len = ntohl (ua->addrlen);
1445  if ('\0' != addrstr[addr_str_len - 1])
1446  {
1447  GNUNET_break (0);
1448  return GNUNET_SYSERR;
1449  }
1450  if (strlen (addrstr) + 1 != addr_str_len)
1451  {
1452  GNUNET_break (0);
1453  return GNUNET_SYSERR;
1454  }
1455 
1456  if (0 == strcmp (plugin->unix_socket_path, addrstr))
1457  return GNUNET_OK;
1458  return GNUNET_SYSERR;
1459 }

References UnixAddress::addrlen, GNUNET_break, GNUNET_OK, GNUNET_SYSERR, and plugin.

Referenced by libgnunet_plugin_transport_unix_init().

Here is the caller graph for this function:

◆ unix_plugin_address_pretty_printer()

static void unix_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
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 1477 of file plugin_transport_unix.c.

1485 {
1486  const char *ret;
1487 
1488  if ((NULL != addr) && (addrlen > 0))
1489  ret = unix_plugin_address_to_string (NULL, addr, addrlen);
1490  else
1491  ret = NULL;
1492  asc (asc_cls, ret, (NULL == ret) ? GNUNET_SYSERR : GNUNET_OK);
1493  asc (asc_cls, NULL, GNUNET_OK);
1494 }

References UnixAddress::addrlen, GNUNET_OK, GNUNET_SYSERR, ret, and unix_plugin_address_to_string().

Referenced by libgnunet_plugin_transport_unix_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ unix_plugin_string_to_address()

static int unix_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 addr (strlen(addr) + '\0')
buflocation to store the buffer If the function returns GNUNET_SYSERR, its contents are undefined.
addedlength of created address
Returns
GNUNET_OK on success, GNUNET_SYSERR on failure

Definition at line 1510 of file plugin_transport_unix.c.

1515 {
1516  struct UnixAddress *ua;
1517  char *address;
1518  char *plugin;
1519  char *optionstr;
1520  uint32_t options;
1521  size_t ua_size;
1522 
1523  /* Format unix.options.address */
1524  address = NULL;
1525  plugin = NULL;
1526  optionstr = NULL;
1527 
1528  if ((NULL == addr) || (addrlen == 0))
1529  {
1530  GNUNET_break (0);
1531  return GNUNET_SYSERR;
1532  }
1533  if ('\0' != addr[addrlen - 1])
1534  {
1535  GNUNET_break (0);
1536  return GNUNET_SYSERR;
1537  }
1538  if (strlen (addr) != addrlen - 1)
1539  {
1540  GNUNET_break (0);
1541  return GNUNET_SYSERR;
1542  }
1543  plugin = GNUNET_strdup (addr);
1544  optionstr = strchr (plugin, '.');
1545  if (NULL == optionstr)
1546  {
1547  GNUNET_break (0);
1548  GNUNET_free (plugin);
1549  return GNUNET_SYSERR;
1550  }
1551  optionstr[0] = '\0';
1552  optionstr++;
1553  options = atol (optionstr);
1554  address = strchr (optionstr, '.');
1555  if (NULL == address)
1556  {
1557  GNUNET_break (0);
1558  GNUNET_free (plugin);
1559  return GNUNET_SYSERR;
1560  }
1561  address[0] = '\0';
1562  address++;
1563  if (0 != strcmp (plugin, PLUGIN_NAME))
1564  {
1565  GNUNET_break (0);
1566  GNUNET_free (plugin);
1567  return GNUNET_SYSERR;
1568  }
1569 
1570  ua_size = sizeof(struct UnixAddress) + strlen (address) + 1;
1571  ua = GNUNET_malloc (ua_size);
1572  ua->options = htonl (options);
1573  ua->addrlen = htonl (strlen (address) + 1);
1574  GNUNET_memcpy (&ua[1], address, strlen (address) + 1);
1575  GNUNET_free (plugin);
1576 
1577  (*buf) = ua;
1578  (*added) = ua_size;
1579  return GNUNET_OK;
1580 }
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.

References address, UnixAddress::addrlen, GNUNET_break, GNUNET_free, GNUNET_malloc, GNUNET_memcpy, GNUNET_OK, GNUNET_strdup, GNUNET_SYSERR, options, UnixAddress::options, plugin, and PLUGIN_NAME.

Referenced by libgnunet_plugin_transport_unix_init().

Here is the caller graph for this function:

◆ address_notification()

static void address_notification ( void *  cls)
static

Notify transport service about address.

Parameters
clsthe plugin

Definition at line 1589 of file plugin_transport_unix.c.

1590 {
1591  struct Plugin *plugin = cls;
1592  struct GNUNET_HELLO_Address *address;
1593  size_t len;
1594  struct UnixAddress *ua;
1595  char *unix_path;
1596 
1597  len = sizeof(struct UnixAddress) + strlen (plugin->unix_socket_path) + 1;
1598  ua = GNUNET_malloc (len);
1599  ua->options = htonl (plugin->myoptions);
1600  ua->addrlen = htonl (strlen (plugin->unix_socket_path) + 1);
1601  unix_path = (char *) &ua[1];
1602  GNUNET_memcpy (unix_path,
1603  plugin->unix_socket_path,
1604  strlen (plugin->unix_socket_path) + 1);
1605 
1606  plugin->address_update_task = NULL;
1607  address = GNUNET_HELLO_address_allocate (plugin->env->my_identity,
1608  PLUGIN_NAME,
1609  ua,
1610  len,
1612  plugin->env->notify_address (plugin->env->cls, GNUNET_YES, address);
1613  GNUNET_free (ua);
1614  GNUNET_free (address);
1615 }

References address, UnixAddress::addrlen, GNUNET_free, GNUNET_HELLO_address_allocate(), GNUNET_HELLO_ADDRESS_INFO_NONE, GNUNET_malloc, GNUNET_memcpy, GNUNET_YES, len, UnixAddress::options, plugin, and PLUGIN_NAME.

Referenced by libgnunet_plugin_transport_unix_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_session_delete_it()

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

Function called on sessions to disconnect.

Parameters
clsthe plugin
keypeer identity (unused)
valuethe struct GNUNET_ATS_Session * to disconnect
Returns
GNUNET_YES (always, continue to iterate)

Definition at line 1627 of file plugin_transport_unix.c.

1630 {
1631  struct Plugin *plugin = cls;
1632  struct GNUNET_ATS_Session *session = value;
1633 
1635  return GNUNET_YES;
1636 }

References GNUNET_YES, plugin, unix_plugin_session_disconnect(), and value.

Referenced by libgnunet_plugin_transport_unix_done(), and unix_plugin_peer_disconnect().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ unix_plugin_peer_disconnect()

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

Disconnect from a remote node.

Clean up session if we have one for this peer

Parameters
clsclosure for this call (should be handle to Plugin)
targetthe peeridentity of the peer to disconnect
Returns
GNUNET_OK on success, GNUNET_SYSERR if the operation failed

Definition at line 1647 of file plugin_transport_unix.c.

1649 {
1650  struct Plugin *plugin = cls;
1651 
1653  target,
1655  plugin);
1656 }
static int get_session_delete_it(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Function called on sessions to disconnect.

References get_session_delete_it(), GNUNET_CONTAINER_multipeermap_get_multiple(), and plugin.

Referenced by libgnunet_plugin_transport_unix_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_session_info_iter()

static int send_session_info_iter ( void *  cls,
const struct GNUNET_PeerIdentity peer,
void *  value 
)
static

Return information about the given session to the monitor callback.

Parameters
clsthe struct Plugin with the monitor callback (sic)
peerpeer we send information about
valueour struct GNUNET_ATS_Session to send information about
Returns
GNUNET_OK (continue to iterate)

Definition at line 1669 of file plugin_transport_unix.c.

1672 {
1673  struct Plugin *plugin = cls;
1674  struct GNUNET_ATS_Session *session = value;
1675 
1678  return GNUNET_OK;
1679 }

References GNUNET_OK, GNUNET_TRANSPORT_SS_INIT, GNUNET_TRANSPORT_SS_UP, notify_session_monitor(), plugin, and value.

Referenced by unix_plugin_setup_monitor().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ unix_plugin_setup_monitor()

static void unix_plugin_setup_monitor ( void *  cls,
GNUNET_TRANSPORT_SessionInfoCallback  sic,
void *  sic_cls 
)
static

Begin monitoring sessions of a plugin.

There can only be one active monitor per plugin (i.e. if there are multiple monitors, the transport service needs to multiplex the generated events over all of them).

Parameters
clsclosure of the plugin
siccallback to invoke, NULL to disable monitor; plugin will being by iterating over all active sessions immediately and then enter monitor mode
sic_clsclosure for sic

Definition at line 1695 of file plugin_transport_unix.c.

1698 {
1699  struct Plugin *plugin = cls;
1700 
1701  plugin->sic = sic;
1702  plugin->sic_cls = sic_cls;
1703  if (NULL != sic)
1704  {
1707  plugin);
1708  /* signal end of first iteration */
1709  sic (sic_cls, NULL, NULL);
1710  }
1711 }
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
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.
void * sic_cls
Closure for sic.
GNUNET_TRANSPORT_SessionInfoCallback sic
Function to call about session status changes.

References GNUNET_CONTAINER_multipeermap_iterate(), plugin, send_session_info_iter(), Plugin::sic, and Plugin::sic_cls.

Referenced by libgnunet_plugin_transport_unix_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ libgnunet_plugin_transport_unix_init()

void* libgnunet_plugin_transport_unix_init ( void *  cls)

The exported method.

Initializes the plugin and returns a struct with the callbacks.

Parameters
clsthe plugin's execution environment
Returns
NULL on error, plugin functions otherwise

Definition at line 1722 of file plugin_transport_unix.c.

1723 {
1726  struct Plugin *plugin;
1727  int sockets_created;
1728 
1729  if (NULL == env->receive)
1730  {
1731  /* run in 'stub' mode (i.e. as part of gnunet-peerinfo), don't fully
1732  initialize the plugin or the API */
1734  api->cls = NULL;
1735  api->address_pretty_printer = &unix_plugin_address_pretty_printer;
1736  api->address_to_string = &unix_plugin_address_to_string;
1737  api->string_to_address = &unix_plugin_string_to_address;
1738  return api;
1739  }
1740 
1741  plugin = GNUNET_new (struct Plugin);
1742  if (GNUNET_OK !=
1744  "transport-unix",
1745  "UNIXPATH",
1746  &plugin->unix_socket_path))
1747  {
1749  "transport-unix",
1750  "UNIXPATH");
1751  GNUNET_free (plugin);
1752  return NULL;
1753  }
1754 
1755  plugin->env = env;
1756 
1757  /* Initialize my flags */
1758 #ifdef __linux__
1759  plugin->is_abstract =
1761  "testing",
1762  "USE_ABSTRACT_SOCKETS");
1763 #endif
1764  plugin->myoptions = UNIX_OPTIONS_NONE;
1765  if (GNUNET_YES == plugin->is_abstract)
1767 
1769  api->cls = plugin;
1770  api->get_session = &unix_plugin_get_session;
1771  api->send = &unix_plugin_send;
1772  api->disconnect_peer = &unix_plugin_peer_disconnect;
1773  api->disconnect_session = &unix_plugin_session_disconnect;
1774  api->query_keepalive_factor = &unix_plugin_query_keepalive_factor;
1775  api->address_pretty_printer = &unix_plugin_address_pretty_printer;
1776  api->address_to_string = &unix_plugin_address_to_string;
1777  api->check_address = &unix_plugin_check_address;
1778  api->string_to_address = &unix_plugin_string_to_address;
1779  api->get_network = &unix_plugin_get_network;
1780  api->get_network_for_address = &unix_plugin_get_network_for_address;
1781  api->update_session_timeout = &unix_plugin_update_session_timeout;
1782  api->setup_monitor = &unix_plugin_setup_monitor;
1783  sockets_created = unix_transport_server_start (plugin);
1784  if ((0 == sockets_created) || (GNUNET_SYSERR == sockets_created))
1785  {
1786  LOG (GNUNET_ERROR_TYPE_WARNING, _ ("Failed to open UNIX listen socket\n"));
1787  GNUNET_free (api);
1788  GNUNET_free (plugin->unix_socket_path);
1789  GNUNET_free (plugin);
1790  return NULL;
1791  }
1793  plugin->address_update_task =
1795  return api;
1796 }
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
enum GNUNET_GenericReturnValue 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.
enum GNUNET_GenericReturnValue 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".
struct GNUNET_CONTAINER_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1299
static void unix_plugin_peer_disconnect(void *cls, const struct GNUNET_PeerIdentity *target)
Disconnect from a remote node.
static int unix_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 correspo...
static void address_notification(void *cls)
Notify transport service about address.
static void unix_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.
static unsigned int unix_plugin_query_keepalive_factor(void *cls)
Function that is called to get the keepalive factor.
static int unix_transport_server_start(void *cls)
Create a slew of UNIX sockets.
static enum GNUNET_NetworkType unix_plugin_get_network_for_address(void *cls, const struct GNUNET_HELLO_Address *address)
Function obtain the network type for a session.
static enum GNUNET_NetworkType unix_plugin_get_network(void *cls, struct GNUNET_ATS_Session *session)
Function obtain the network type for a session.
static void unix_plugin_setup_monitor(void *cls, GNUNET_TRANSPORT_SessionInfoCallback sic, void *sic_cls)
Begin monitoring sessions of a plugin.
static int unix_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.
static void unix_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...
static ssize_t unix_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.
void * cls
Closure for all of the callbacks.
The transport service will pass a pointer to a struct of this type as the first and only argument to ...
void * cls
Closure for the various callbacks.
Each plugin is required to return a pointer to a struct of this type as the return value from its ent...
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
Definition: block.c:47

References _, address_notification(), Plugin::api, GNUNET_BLOCK_PluginFunctions::cls, GNUNET_TRANSPORT_PluginEnvironment::cls, env, GNUNET_CONFIGURATION_get_value_filename(), GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_CONTAINER_multipeermap_create(), GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log_config_missing(), GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_SYSERR, GNUNET_YES, LOG, plugin, UNIX_OPTIONS_NONE, UNIX_OPTIONS_USE_ABSTRACT_SOCKETS, unix_plugin_address_pretty_printer(), unix_plugin_address_to_string(), unix_plugin_check_address(), unix_plugin_get_network(), unix_plugin_get_network_for_address(), unix_plugin_get_session(), unix_plugin_peer_disconnect(), unix_plugin_query_keepalive_factor(), unix_plugin_send(), unix_plugin_session_disconnect(), unix_plugin_setup_monitor(), unix_plugin_string_to_address(), unix_plugin_update_session_timeout(), and unix_transport_server_start().

Here is the call graph for this function:

◆ libgnunet_plugin_transport_unix_done()

void* libgnunet_plugin_transport_unix_done ( void *  cls)

Shutdown the plugin.

Parameters
clsthe plugin API returned from the initialization function
Returns
NULL (always)

Definition at line 1806 of file plugin_transport_unix.c.

1807 {
1808  struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
1809  struct Plugin *plugin = api->cls;
1810  struct GNUNET_HELLO_Address *address;
1811  struct UNIXMessageWrapper *msgw;
1812  struct UnixAddress *ua;
1813  size_t len;
1814  struct GNUNET_ATS_Session *session;
1815 
1816  if (NULL == plugin)
1817  {
1818  GNUNET_free (api);
1819  return NULL;
1820  }
1821  len = sizeof(struct UnixAddress) + strlen (plugin->unix_socket_path) + 1;
1822  ua = GNUNET_malloc (len);
1823  ua->options = htonl (plugin->myoptions);
1824  ua->addrlen = htonl (strlen (plugin->unix_socket_path) + 1);
1825  GNUNET_memcpy (&ua[1],
1826  plugin->unix_socket_path,
1827  strlen (plugin->unix_socket_path) + 1);
1828  address = GNUNET_HELLO_address_allocate (plugin->env->my_identity,
1829  PLUGIN_NAME,
1830  ua,
1831  len,
1833  plugin->env->notify_address (plugin->env->cls, GNUNET_NO, address);
1834 
1835  GNUNET_free (address);
1836  GNUNET_free (ua);
1837 
1838  while (NULL != (msgw = plugin->msg_head))
1839  {
1840  GNUNET_CONTAINER_DLL_remove (plugin->msg_head, plugin->msg_tail, msgw);
1841  session = msgw->session;
1842  session->msgs_in_queue--;
1843  GNUNET_assert (session->bytes_in_queue >= msgw->msgsize);
1844  session->bytes_in_queue -= msgw->msgsize;
1845  GNUNET_assert (plugin->bytes_in_queue >= msgw->msgsize);
1846  plugin->bytes_in_queue -= msgw->msgsize;
1847  if (NULL != msgw->cont)
1848  msgw->cont (msgw->cont_cls,
1849  &msgw->session->target,
1850  GNUNET_SYSERR,
1851  msgw->payload,
1852  0);
1853  GNUNET_free (msgw->msg);
1854  GNUNET_free (msgw);
1855  }
1856 
1857  if (NULL != plugin->read_task)
1858  {
1859  GNUNET_SCHEDULER_cancel (plugin->read_task);
1860  plugin->read_task = NULL;
1861  }
1862  if (NULL != plugin->write_task)
1863  {
1864  GNUNET_SCHEDULER_cancel (plugin->write_task);
1865  plugin->write_task = NULL;
1866  }
1867  if (NULL != plugin->address_update_task)
1868  {
1869  GNUNET_SCHEDULER_cancel (plugin->address_update_task);
1870  plugin->address_update_task = NULL;
1871  }
1872  if (NULL != plugin->unix_sock.desc)
1873  {
1875  GNUNET_NETWORK_socket_close (plugin->unix_sock.desc));
1876  plugin->unix_sock.desc = NULL;
1877  }
1880  plugin);
1882  GNUNET_break (0 == plugin->bytes_in_queue);
1883  GNUNET_free (plugin->unix_socket_path);
1884  GNUNET_free (plugin);
1885  GNUNET_free (api);
1886  return NULL;
1887 }
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
void * cls
Closure for all of the callbacks.

References address, UnixAddress::addrlen, Plugin::api, GNUNET_ATS_Session::bytes_in_queue, GNUNET_BLOCK_PluginFunctions::cls, GNUNET_TRANSPORT_PluginFunctions::cls, UNIXMessageWrapper::cont, UNIXMessageWrapper::cont_cls, get_session_delete_it(), GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multipeermap_destroy(), GNUNET_CONTAINER_multipeermap_iterate(), GNUNET_free, GNUNET_HELLO_address_allocate(), GNUNET_HELLO_ADDRESS_INFO_NONE, GNUNET_malloc, GNUNET_memcpy, GNUNET_NETWORK_socket_close(), GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_cancel(), GNUNET_SYSERR, len, UNIXMessageWrapper::msg, GNUNET_ATS_Session::msgs_in_queue, UNIXMessageWrapper::msgsize, UnixAddress::options, UNIXMessageWrapper::payload, plugin, PLUGIN_NAME, UNIXMessageWrapper::session, and GNUNET_ATS_Session::target.

Here is the call graph for this function: