Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

sockets.c File Reference


Detailed Description

Socket management.

Author:
Daniel Walker (dwalker@cats.ucsc.edu)
Date:
2000
Author:
Raphael Manfredi
Date:
2001-2003

#include "common.h"
#include "sockets.h"
#include "downloads.h"
#include "uploads.h"
#include "parq.h"
#include "nodes.h"
#include "bsched.h"
#include "ban.h"
#include "http.h"
#include "inet.h"
#include "hostiles.h"
#include "pproxy.h"
#include "udp.h"
#include "settings.h"
#include "if/gnet_property.h"
#include "if/gnet_property_priv.h"
#include "lib/socket.h"
#include "lib/adns.h"
#include "lib/getline.h"
#include "lib/glib-missing.h"
#include "lib/endian.h"
#include "lib/header.h"
#include "lib/tm.h"
#include "lib/walloc.h"
#include "lib/override.h"

Data Structures

union  socket_addr
struct  socket_linger

Defines

#define SHUT_WR   1 /**< Shutdown TX side */
 Shutdown TX side.

#define RQST_LINE_LENGTH   256 /**< Reasonable estimate for request line */
 Reasonable estimate for request line.

#define SOCK_UDP_RECV_BUF   131072 /**< 128K -- Large to avoid loosing dgrams */
 128K -- Large to avoid loosing dgrams

#define SOCK_ADNS_PENDING   0x01 /**< Don't free() the socket too early */
 Don't free() the socket too early.

#define SOCK_ADNS_FAILED   0x02 /**< Signals error in the ADNS callback */
 Signals error in the ADNS callback.

#define SOCK_ADNS_BADNAME   0x04 /**< Signals bad host name */
 Signals bad host name.


Typedefs

typedef socket_addr socket_addr_t

Functions

 RCSID ("$Id:sockets.c, v 1.88 2005/12/27 16:37:22 cbiere Exp $")
void socket_addr_set (socket_addr_t *addr, const host_addr_t ha, guint16 port)
 Initializes addr with an IPv4 address and a port number.

host_addr_t socket_addr_get_addr (const socket_addr_t *addr)
 Retrieves the address from a socket_addr_t.

guint16 socket_addr_get_port (const socket_addr_t *addr)
 Retrieves the port number from a socket_addr_t.

socklen_t socket_addr_get (const socket_addr_t *addr, const struct sockaddr **p_sa)
 Grab a generic sockaddr structure pointer from the socket address `addr' which can be either an IPv4 or IPv6 socket address.

gint socket_evt_fd (struct gnutella_socket *s)
 Return the file descriptor to use for I/O monitoring callbacks on the socket.

void socket_evt_set (struct gnutella_socket *s, inputevt_cond_t cond, inputevt_handler_t handler, gpointer data)
 Install handler callback when an input condition is satisfied on the socket.

void socket_evt_clear (struct gnutella_socket *s)
 Remove I/O readiness monitoring on the socket.

void socket_evt_change (struct gnutella_socket *s, inputevt_cond_t cond)
 Change the monitoring condition on the socket.

void socket_register_fd_reclaimer (reclaim_fd_t callback)
 Register fd reclaiming callback.

void guess_local_addr (int sd)
 Tries to guess the local IP address.

void socket_destroy (struct gnutella_socket *s, const gchar *reason)
 Destroy a socket.

void socket_connected (gpointer data, gint source, inputevt_cond_t cond)
 Callback for outgoing connections!

void socket_wio_link (struct gnutella_socket *s)
void get_sol (void)
 Compute and cache values for SOL_TCP and SOL_IP.

gint sol_tcp (void)
gint sol_ip (void)
gint socket_tos (const struct gnutella_socket *unused_s, gint unused_tos)
void socket_tos_default (const struct gnutella_socket *unused_s)
void socket_tos_normal (const struct gnutella_socket *s)
 Set the Type of Service (TOS) field to "normal.".

void socket_tos_lowdelay (const struct gnutella_socket *s)
 Set the Type of Service (TOS) field to "lowdelay." This may cause your host and/or any routers along the path to put its packets in a higher-priority queue, and/or to route them along the lowest- latency path without regard for bandwidth.

void socket_tos_throughput (const struct gnutella_socket *s)
 Set the Type of Service (TOS) field to "throughput." This may cause your host and/or any routers along the path to put its packets in a lower-priority queue, and/or to route them along the highest- bandwidth path without regard for latency.

void socket_eof (struct gnutella_socket *s)
 Got an EOF condition on the socket.

void proxy_connect_helper (const host_addr_t *addr, gpointer udata)
int proxy_connect (int fd)
gint send_socks4 (struct gnutella_socket *s)
gint recv_socks4 (struct gnutella_socket *s)
gint connect_http (struct gnutella_socket *s)
gint connect_socksv5 (struct gnutella_socket *s)
void socket_timer (time_t now)
 Called by main timer.

void socket_shutdown (void)
 Cleanup data structures on shutdown.

void socket_linger_cb (gpointer data, gint fd, inputevt_cond_t unused_cond)
void socket_linger_close (gint fd)
void socket_free (struct gnutella_socket *s)
 Dispose of socket, closing connection, removing input callback, and reclaiming attached getline buffer.

void socket_read (gpointer data, gint source, inputevt_cond_t cond)
 Used for incoming connections, for outgoing too?? Read bytes on an unknown incoming socket.

int socket_addr_getsockname (socket_addr_t *p_addr, int fd)
int socket_local_port (struct gnutella_socket *s)
void socket_accept (gpointer data, gint unused_source, inputevt_cond_t cond)
 Someone is connecting to us.

gboolean socket_udp_accept (struct gnutella_socket *s)
 Someone is sending us a datagram.

void socket_udp_event (gpointer data, gint unused_source, inputevt_cond_t cond)
 Someone is sending us a datagram.

void socket_set_linger (gint fd)
gint socket_connect_prepare (struct gnutella_socket *s, const host_addr_t ha, guint16 port, enum socket_type type, guint32 flags)
 Called to prepare the creation of the socket connection.

gint socket_connect_finalize (struct gnutella_socket *s, const host_addr_t ha)
 Called to finalize the creation of the socket connection, which is done in two steps since DNS resolving is asynchronous.

gnutella_socketsocket_connect (const host_addr_t ha, guint16 port, enum socket_type type, guint32 flags)
 Creates a connected socket with an attached resource of `type'.

gboolean socket_bad_hostname (struct gnutella_socket *s)
void socket_connect_by_name_helper (const host_addr_t *addr, gpointer user_data)
 Called when we got a reply from the ADNS process.

gnutella_socketsocket_connect_by_name (const gchar *host, guint16 port, enum socket_type type, guint32 flags)
 Like socket_connect() but the remote address is not known and must be resolved through async DNS calls.

gnutella_socketsocket_tcp_listen (const host_addr_t ha, guint16 port, enum socket_type type)
 Creates a non-blocking TCP listening socket with an attached resource of `type'.

gnutella_socketsocket_udp_listen (const host_addr_t ha, guint16 port)
 Creates a non-blocking listening UDP socket.

void sock_cork (struct gnutella_socket *s, gboolean on)
 Set/clear TCP_CORK on the socket.

void sock_set_intern (gint fd, gint option, gint size, gchar *type, gboolean shrink)
void sock_send_buf (struct gnutella_socket *s, gint size, gboolean shrink)
 Set socket's send buffer to specified size.

void sock_recv_buf (struct gnutella_socket *s, gint size, gboolean shrink)
 Set socket's receive buffer to specified size.

void sock_nodelay (struct gnutella_socket *s, gboolean on)
 Turn TCP_NODELAY on or off on the socket.

void sock_tx_shutdown (struct gnutella_socket *s)
 Shutdown the TX side of the socket.

int socket_get_fd (struct wrap_io *wio)
ssize_t socket_plain_write (struct wrap_io *wio, gconstpointer buf, size_t size)
ssize_t socket_plain_read (struct wrap_io *wio, gpointer buf, size_t size)
ssize_t socket_plain_writev (struct wrap_io *wio, const struct iovec *iov, int iovcnt)
ssize_t socket_plain_readv (struct wrap_io *wio, struct iovec *iov, int iovcnt)
ssize_t socket_plain_sendto (struct wrap_io *wio, gnet_host_t *to, gconstpointer buf, size_t size)
ssize_t socket_no_sendto (struct wrap_io *unused_wio, gnet_host_t *unused_to, gconstpointer unused_buf, size_t unused_size)
ssize_t socket_no_write (struct wrap_io *unused_wio, gconstpointer unused_buf, size_t unused_size)
ssize_t socket_no_writev (struct wrap_io *unused_wio, const struct iovec *unused_iov, int unused_iovcnt)
ssize_t safe_readv (wrap_io_t *wio, struct iovec *iov, gint iovcnt)
 Wrapper over readv() ensuring that we don't request more than MAX_IOV_COUNT entries at a time.

ssize_t safe_writev (wrap_io_t *wio, struct iovec *iov, gint iovcnt)
 Wrapper over writev() ensuring that we don't request more than MAX_IOV_COUNT entries at a time.

ssize_t safe_writev_fd (gint fd, struct iovec *iov, gint iovcnt)
 Wrapper over writev() ensuring that we don't request more than MAX_IOV_COUNT entries at a time.

void socket_init (void)

Variables

gnutella_sockets_tcp_listen = NULL
gnutella_sockets_udp_listen = NULL
reclaim_fd_t reclaim_fd = NULL
gboolean ip_computed = FALSE
GSList * sl_incoming = NULL
 To spot inactive sockets.

gboolean sol_got = FALSE
gint sol_tcp_cached = -1
gint sol_ip_cached = -1


Define Documentation

#define RQST_LINE_LENGTH   256 /**< Reasonable estimate for request line */
 

Reasonable estimate for request line.

#define SHUT_WR   1 /**< Shutdown TX side */
 

Shutdown TX side.

#define SOCK_ADNS_BADNAME   0x04 /**< Signals bad host name */
 

Signals bad host name.

#define SOCK_ADNS_FAILED   0x02 /**< Signals error in the ADNS callback */
 

Signals error in the ADNS callback.

#define SOCK_ADNS_PENDING   0x01 /**< Don't free() the socket too early */
 

Don't free() the socket too early.

#define SOCK_UDP_RECV_BUF   131072 /**< 128K -- Large to avoid loosing dgrams */
 

128K -- Large to avoid loosing dgrams


Typedef Documentation

typedef union socket_addr socket_addr_t
 


Function Documentation

gint connect_http struct gnutella_socket s  )  [static]
 

gint connect_socksv5 struct gnutella_socket s  )  [static]
 

void get_sol void   )  [static]
 

Compute and cache values for SOL_TCP and SOL_IP.

void guess_local_addr int  fd  )  [static]
 

Tries to guess the local IP address.

int proxy_connect int  fd  )  [static]
 

void proxy_connect_helper const host_addr_t addr,
gpointer  udata
[static]
 

RCSID "$Id:sockets.  c,
v 1.88 2005/12/27 16:37:22 cbiere Exp $" 
 

gint recv_socks4 struct gnutella_socket s  )  [static]
 

ssize_t safe_readv wrap_io_t wio,
struct iovec *  iov,
gint  iovcnt
 

Wrapper over readv() ensuring that we don't request more than MAX_IOV_COUNT entries at a time.

ssize_t safe_writev wrap_io_t wio,
struct iovec *  iov,
gint  iovcnt
 

Wrapper over writev() ensuring that we don't request more than MAX_IOV_COUNT entries at a time.

ssize_t safe_writev_fd gint  fd,
struct iovec *  iov,
gint  iovcnt
 

Wrapper over writev() ensuring that we don't request more than MAX_IOV_COUNT entries at a time.

gint send_socks4 struct gnutella_socket s  )  [static]
 

void sock_cork struct gnutella_socket s,
gboolean  on
 

Set/clear TCP_CORK on the socket.

When set, TCP will only send out full TCP/IP frames. The exact size depends on your LAN interface, but on Ethernet, it's about 1500 bytes.

void sock_nodelay struct gnutella_socket s,
gboolean  on
 

Turn TCP_NODELAY on or off on the socket.

void sock_recv_buf struct gnutella_socket s,
gint  size,
gboolean  shrink
 

Set socket's receive buffer to specified size.

If `shrink' is false, refuse to shrink the buffer if its size is larger.

void sock_send_buf struct gnutella_socket s,
gint  size,
gboolean  shrink
 

Set socket's send buffer to specified size.

If `shrink' is false, refuse to shrink the buffer if its size is larger.

void sock_set_intern gint  fd,
gint  option,
gint  size,
gchar *  type,
gboolean  shrink
[static]
 

void sock_tx_shutdown struct gnutella_socket s  ) 
 

Shutdown the TX side of the socket.

void socket_accept gpointer  data,
gint  unused_source,
inputevt_cond_t  cond
[static]
 

Someone is connecting to us.

socklen_t socket_addr_get const socket_addr_t addr,
const struct sockaddr **  p_sa
[static]
 

Grab a generic sockaddr structure pointer from the socket address `addr' which can be either an IPv4 or IPv6 socket address.

Returns:
the length of the generic sockaddr structure, with `p_sa' filled with the pointer to the start of the structure.

host_addr_t socket_addr_get_addr const socket_addr_t addr  )  [inline, static]
 

Retrieves the address from a socket_addr_t.

Parameters:
addr a pointer to an initialized socket_addr_t
Returns:
the address.

guint16 socket_addr_get_port const socket_addr_t addr  )  [inline, static]
 

Retrieves the port number from a socket_addr_t.

Parameters:
addr a pointer to an initialized socket_addr_t
Returns:
the port number in host byte order

int socket_addr_getsockname socket_addr_t p_addr,
int  fd
[static]
 

void socket_addr_set socket_addr_t addr,
const host_addr_t  ha,
guint16  port
[static]
 

Initializes addr with an IPv4 address and a port number.

Parameters:
addr a pointer to a socket_addr_t
ha an IPv4 address in host(!) byte order
port a 16-bit port number in host byte order

gboolean socket_bad_hostname struct gnutella_socket s  ) 
 

Returns:
whether bad hostname was reported after a DNS lookup.

struct gnutella_socket* socket_connect const host_addr_t  ha,
guint16  port,
enum socket_type  type,
guint32  flags
 

Creates a connected socket with an attached resource of `type'.

Connection happens in the background, the connection callback being determined by the resource type.

struct gnutella_socket* socket_connect_by_name const gchar *  host,
guint16  port,
enum socket_type  type,
guint32  flags
 

Like socket_connect() but the remote address is not known and must be resolved through async DNS calls.

void socket_connect_by_name_helper const host_addr_t addr,
gpointer  user_data
[static]
 

Called when we got a reply from the ADNS process.

Todo:
TODO: All resolved addresses should be attempted.

gint socket_connect_finalize struct gnutella_socket s,
const host_addr_t  ha
[static]
 

Called to finalize the creation of the socket connection, which is done in two steps since DNS resolving is asynchronous.

Returns:
non-zero in case of failure, zero on success.

gint socket_connect_prepare struct gnutella_socket s,
const host_addr_t  ha,
guint16  port,
enum socket_type  type,
guint32  flags
[static]
 

Called to prepare the creation of the socket connection.

Returns:
non-zero in case of failure, zero on success.

void socket_connected gpointer  data,
gint  source,
inputevt_cond_t  cond
[static]
 

Callback for outgoing connections!

Called when a socket is connected. Checks type of connection and hands control over the connetion over to more specialized handlers. If no handler was found the connection is terminated. This is the place to hook up handlers for new communication types. So far there are CONTROL, UPLOAD, DOWNLOAD and HTTP handlers.

void socket_destroy struct gnutella_socket s,
const gchar *  reason
[static]
 

Destroy a socket.

If there is an attached resource, call the resource's termination routine with the supplied reason.

void socket_eof struct gnutella_socket s  ) 
 

Got an EOF condition on the socket.

void socket_evt_change struct gnutella_socket s,
inputevt_cond_t  cond
 

Change the monitoring condition on the socket.

Note:
Triggered only on TLS sockets.

void socket_evt_clear struct gnutella_socket s  ) 
 

Remove I/O readiness monitoring on the socket.

gint socket_evt_fd struct gnutella_socket s  )  [static]
 

Return the file descriptor to use for I/O monitoring callbacks on the socket.

void socket_evt_set struct gnutella_socket s,
inputevt_cond_t  cond,
inputevt_handler_t  handler,
gpointer  data
 

Install handler callback when an input condition is satisfied on the socket.

Parameters:
s the socket
cond Any INPUT_EVENT_* except INPUT_EVENT_EXCEPTION.
handler the handler callback to invoke when condition is satisfied
data opaque data to supply to the callback
Note:
When monitoring for INPUT_EVENT_RW(X), both INPUT_EVENT_R and INPUT_EVENT_W flags can be set at the same time when the callback is invoked.

void socket_free struct gnutella_socket s  ) 
 

Dispose of socket, closing connection, removing input callback, and reclaiming attached getline buffer.

int socket_get_fd struct wrap_io wio  )  [static]
 

void socket_init void   ) 
 

void socket_linger_cb gpointer  data,
gint  fd,
inputevt_cond_t  unused_cond
[static]
 

void socket_linger_close gint  fd  )  [static]
 

int socket_local_port struct gnutella_socket s  )  [static]
 

Returns:
socket's local port, or -1 on error.

ssize_t socket_no_sendto struct wrap_io unused_wio,
gnet_host_t unused_to,
gconstpointer  unused_buf,
size_t  unused_size
[static]
 

ssize_t socket_no_write struct wrap_io unused_wio,
gconstpointer  unused_buf,
size_t  unused_size
[static]
 

ssize_t socket_no_writev struct wrap_io unused_wio,
const struct iovec *  unused_iov,
int  unused_iovcnt
[static]
 

ssize_t socket_plain_read struct wrap_io wio,
gpointer  buf,
size_t  size
[static]
 

ssize_t socket_plain_readv struct wrap_io wio,
struct iovec *  iov,
int  iovcnt
[static]
 

ssize_t socket_plain_sendto struct wrap_io wio,
gnet_host_t to,
gconstpointer  buf,
size_t  size
[static]
 

ssize_t socket_plain_write struct wrap_io wio,
gconstpointer  buf,
size_t  size
[static]
 

ssize_t socket_plain_writev struct wrap_io wio,
const struct iovec *  iov,
int  iovcnt
[static]
 

void socket_read gpointer  data,
gint  source,
inputevt_cond_t  cond
[static]
 

Used for incoming connections, for outgoing too?? Read bytes on an unknown incoming socket.

When the first line has been read it's decided on what type cof connection this is. If the first line is not complete on the first call, this function will be called as often as necessary to fetch a full line.

void socket_register_fd_reclaimer reclaim_fd_t  callback  ) 
 

Register fd reclaiming callback.

Use NULL to unregister it.

void socket_set_linger gint  fd  )  [inline, static]
 

void socket_shutdown void   ) 
 

Cleanup data structures on shutdown.

struct gnutella_socket* socket_tcp_listen const host_addr_t  ha,
guint16  port,
enum socket_type  type
 

Creates a non-blocking TCP listening socket with an attached resource of `type'.

void socket_timer time_t  now  ) 
 

Called by main timer.

Expires inactive sockets.

gint socket_tos const struct gnutella_socket unused_s,
gint  unused_tos
[static]
 

void socket_tos_default const struct gnutella_socket unused_s  ) 
 

void socket_tos_lowdelay const struct gnutella_socket s  ) 
 

Set the Type of Service (TOS) field to "lowdelay." This may cause your host and/or any routers along the path to put its packets in a higher-priority queue, and/or to route them along the lowest- latency path without regard for bandwidth.

void socket_tos_normal const struct gnutella_socket s  ) 
 

Set the Type of Service (TOS) field to "normal.".

void socket_tos_throughput const struct gnutella_socket s  ) 
 

Set the Type of Service (TOS) field to "throughput." This may cause your host and/or any routers along the path to put its packets in a lower-priority queue, and/or to route them along the highest- bandwidth path without regard for latency.

gboolean socket_udp_accept struct gnutella_socket s  )  [static]
 

Someone is sending us a datagram.

void socket_udp_event gpointer  data,
gint  unused_source,
inputevt_cond_t  cond
[static]
 

Someone is sending us a datagram.

struct gnutella_socket* socket_udp_listen const host_addr_t  ha,
guint16  port
 

Creates a non-blocking listening UDP socket.

void socket_wio_link struct gnutella_socket s  )  [static]
 

gint sol_ip void   )  [static]
 

Returns:
SOL_IP.

gint sol_tcp void   )  [static]
 

Returns:
SOL_TCP.


Variable Documentation

gboolean ip_computed = FALSE [static]
 

reclaim_fd_t reclaim_fd = NULL [static]
 

struct gnutella_socket* s_tcp_listen = NULL
 

struct gnutella_socket* s_udp_listen = NULL
 

GSList* sl_incoming = NULL [static]
 

To spot inactive sockets.

gboolean sol_got = FALSE [static]
 

gint sol_ip_cached = -1 [static]
 

gint sol_tcp_cached = -1 [static]
 


Generated on Sun Feb 12 10:50:08 2006 for Gtk-Gnutella by doxygen 1.3.6