Commit 2339cbaf authored by Pekka Pessi's avatar Pekka Pessi

Split tport.c into multiple modules.

STUN, UPnP and SigComp still need some polishing.

darcs-hash:20060324115822-88462-bffca4ccb55a45c029ec83c39baf953824af8237.gz
parent 6b0afff4
......@@ -30,16 +30,20 @@ TESTS = test_tport
nobase_include_sofia_HEADERS = \
sofia-sip/tport.h sofia-sip/tport_tag.h
TLS_SRC = tport_tls.c tport_tls.h
TLS_SRC = tport_type_tls.c tport_tls.c tport_tls.h
if HAVE_TLS
USE_TLS_SRC = $(TLS_SRC)
endif
libtport_la_SOURCES = tport.c tport_tag.c tport_tag_ref.c $(USE_TLS_SRC)
libtport_la_SOURCES = tport.c tport_logging.c \
tport_type_udp.c tport_type_tcp.c \
tport_type_sctp.c tport_type_connect.c \
tport_threadpool.c tport_internal.h \
tport_tag.c tport_tag_ref.c $(USE_TLS_SRC)
# to make sure all files end up in the dist package
EXTRA_libtport_la_SOURCES = $(TLS_SRC)
EXTRA_libtport_la_SOURCES = $(TLS_SRC) tport_sigcomp.c tport_stun.c
BUILT_SOURCES = tport_tag_ref.c
......
......@@ -35,8 +35,6 @@
#include "config.h"
#undef HAVE_TLS
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
......@@ -346,7 +344,7 @@ static int new_test_msg(tp_test_t *tt, msg_t **retval,
static
struct sigcomp_compartment *
tp_sigcomp_compartment(tp_test_t *tt, tport_t *tp, tp_name_t const *tpn);
test_sigcomp_compartment(tp_test_t *tt, tport_t *tp, tp_name_t const *tpn);
static void tp_test_recv(tp_test_t *tt,
tport_t *tp,
......@@ -358,7 +356,7 @@ static void tp_test_recv(tp_test_t *tt,
tp_name_t frm[1];
if (tport_delivered_from(tp, msg, frm) != -1 && frm->tpn_comp) {
struct sigcomp_compartment *cc = tp_sigcomp_compartment(tt, tp, frm);
struct sigcomp_compartment *cc = test_sigcomp_compartment(tt, tp, frm);
tport_sigcomp_accept(tp, cc, msg);
}
......@@ -403,9 +401,9 @@ msg_t *tp_test_msg(tp_test_t *tt, int flags,
static
struct sigcomp_compartment *
tp_sigcomp_compartment(tp_test_t *tt,
tport_t *tp,
tp_name_t const *tpn)
test_sigcomp_compartment(tp_test_t *tt,
tport_t *tp,
tp_name_t const *tpn)
{
struct sigcomp_compartment *cc = NULL;
#if HAVE_SIGCOMP
......@@ -435,11 +433,11 @@ tp_sigcomp_compartment(tp_test_t *tt,
}
/* Accept/reject early SigComp message */
int tp_sigcomp_accept(tp_stack_t *tt, tport_t *tp, msg_t *msg)
int test_sigcomp_accept(tp_stack_t *tt, tport_t *tp, msg_t *msg)
{
struct sigcomp_compartment *cc = NULL;
cc = tp_sigcomp_compartment(tt, tp, tport_name(tp));
cc = test_sigcomp_compartment(tt, tp, tport_name(tp));
if (cc)
tport_sigcomp_assign(tp, cc);
......@@ -454,7 +452,7 @@ tp_stack_class_t const tp_test_class[1] =
/* tpac_recv */ tp_test_recv,
/* tpac_error */ tp_test_error,
/* tpac_alloc */ tp_test_msg,
/* tpac_sigcomp_accept */ tp_sigcomp_accept
/* tpac_sigcomp_accept */ test_sigcomp_accept
}};
static int init_test(tp_test_t *tt)
......@@ -1115,7 +1113,7 @@ static int sigcomp_test(tp_test_t *tt)
if (tt->tt_udp_comp->tpn_comp) {
msg_t *msg = NULL;
TEST_1(cc = tp_sigcomp_compartment(tt, tt->tt_tports, tt->tt_udp_comp));
TEST_1(cc = test_sigcomp_compartment(tt, tt->tt_tports, tt->tt_udp_comp));
TEST_1(!new_test_msg(tt, &msg, "udp-sigcomp", 1, 1200));
test_create_md5(tt, msg);
......@@ -1141,7 +1139,7 @@ static int sigcomp_test(tp_test_t *tt)
tpn->tpn_comp = tport_name(tt->tt_rtport)->tpn_comp;
/* reply */
TEST_1(cc = tp_sigcomp_compartment(tt, tt->tt_tports, tpn));
TEST_1(cc = test_sigcomp_compartment(tt, tt->tt_tports, tpn));
TEST_1(tport_tsend(tt->tt_rtport, msg, tpn,
TPTAG_COMPARTMENT(cc),
TAG_END()) != NULL);
......@@ -1166,7 +1164,7 @@ static int sigcomp_test(tp_test_t *tt)
tport_log->log_level = 9;
TEST_1(cc = tp_sigcomp_compartment(tt, tt->tt_tports, tpn));
TEST_1(cc = test_sigcomp_compartment(tt, tt->tt_tports, tpn));
TEST_1(tp = tport_tsend(tt->tt_tports,
msg,
tpn,
......
This diff is collapsed.
/*
* This file is part of the Sofia-SIP package
*
* Copyright (C) 2005 Nokia Corporation.
*
* Contact: Pekka Pessi <pekka.pessi@nokia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
#ifndef TPORT_INTERNAL_H /** Defined when <tport.h> has been included. */
#define TPORT_INTERNAL_H
/**@file tport_internal.h
* @brief Transport interface
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
*
* @date Created: Thu Jun 29 15:58:06 2000 ppessi
*/
#ifndef SU_H
#include <sofia-sip/su.h>
#endif
#include <sofia-sip/su_uniqueid.h>
#ifndef MSG_ADDR_H
#include <sofia-sip/msg_addr.h>
#endif
#ifndef TPORT_H
#include <sofia-sip/tport.h>
#endif
#if HAVE_SOFIA_STUN
#include "sofia-sip/stun.h"
#include "sofia-sip/stun_tag.h"
#endif
#ifndef SU_DEBUG
#define SU_DEBUG 3
#endif
#define SU_LOG tport_log
#include <sofia-sip/su_debug.h>
#if !defined(MSG_NOSIGNAL) || defined(__CYGWIN__)
#undef MSG_NOSIGNAL
#define MSG_NOSIGNAL (0)
#endif
#if !defined(MSG_TRUNC) || defined(SU_HAVE_WINSOCK)
#undef MSG_TRUNC
#define MSG_TRUNC (0)
#endif
#ifndef NONE
#define NONE ((void *)-1)
#endif
SOFIA_BEGIN_DECLS
#undef HAVE_SIGCOMP
typedef struct tport_master tport_master_t;
typedef struct tport_pending_s tport_pending_t;
typedef struct tport_threadpool tport_threadpool_t;
typedef struct tport_sigcomp_handler tport_sigcomp_handler_t;
typedef struct tport_sigcomp tport_sigcomp_t;
typedef struct tport_primary tport_primary_t;
typedef struct tport_vtable tport_vtable_t;
struct sigcomp_state_handler;
struct sigcomp_algorithm;
struct sigcomp_udvm;
struct sigcomp_magic;
struct sigcomp_compartment;
typedef long unsigned LU; /* for printf() and friends */
#if HAVE_SIGCOMP
/** Per-socket SigComp data */
struct tport_sigcomp {
struct sigcomp_udvm *sc_udvm;
struct sigcomp_compartment *sc_cc;
struct sigcomp_compressor *sc_compressor;
struct sigcomp_buffer *sc_output;
unsigned sc_compressed;
struct sigcomp_buffer *sc_input;
unsigned sc_copied;
enum {
format_is_unknown,
format_is_sigcomp,
format_is_noncomp
} sc_infmt, sc_outfmt;
};
#endif
/** Transport parameters */
typedef struct {
unsigned tpp_mtu; /**< Maximum packet size */
unsigned tpp_idle; /**< Allowed connection idle time. */
unsigned tpp_timeout; /**< Allowed idle time for message. */
unsigned tpp_sigcomp_lifetime; /**< SigComp compartment lifetime */
unsigned tpp_thrpsize; /**< Size of thread pool */
unsigned tpp_thrprqsize; /**< Length of per-thread recv queue */
unsigned tpp_qsize; /**< Size of queue */
unsigned tpp_drop; /**< Packet drop probablity */
unsigned tpp_conn_orient:1; /**< Connection-orienteded */
unsigned tpp_sdwn_error:1; /**< If true, shutdown is error. */
unsigned :0;
} tport_params_t;
/** Transport object.
*
* A transport object can be used in three roles, to represent transport
* list (aka master transport), to represent available transports (aka
* primary transport) and to represent actual transport connections (aka
* secondary transport).
*/
struct tport_s {
su_home_t tp_home[1]; /**< Memory home */
int tp_refs; /**< Number of references to tport */
unsigned tp_black:1; /**< Used by red-black-tree */
unsigned tp_accepted:1; /**< Originally server? */
unsigned tp_conn_orient:1; /**< Is connection-oriented */
unsigned tp_connected : 1; /**< Has real connection */
unsigned tp_reusable:1; /**< Can this connection be reused */
unsigned tp_closed : 1; /**< This transport is closed */
/**< Remote end has sent FIN (2) or we should not just read */
unsigned tp_recv_close:2;
/** We will send FIN (1) or have sent FIN (2) */
unsigned tp_send_close:2;
unsigned tp_has_keepalive:1;
unsigned:0;
tport_t *tp_left, *tp_right, *tp_dad; /**< Links in tport tree */
tport_master_t *tp_master; /**< Master transport */
tport_primary_t *tp_pri; /**< Primary transport */
tport_params_t *tp_params; /**< Transport parameters */
tp_magic_t *tp_magic; /**< Context provided by consumer */
msg_t const *tp_rlogged; /**< Last logged when receiving */
msg_t const *tp_slogged; /**< Last logged when sending */
unsigned tp_time; /**< When this transport was last used */
tp_name_t tp_name[1]; /**< Transport name.
*
* This is either our name (if primary)
* or peer name (if secondary).
*/
#define tp_protoname tp_name->tpn_proto
#define tp_canon tp_name->tpn_canon
#define tp_host tp_name->tpn_host
#define tp_port tp_name->tpn_port
#define tp_ident tp_name->tpn_ident
su_socket_t tp_socket; /**< Socket of this tport*/
int tp_index; /**< Root registration index */
int tp_events; /**< Subscribed events */
su_addrinfo_t tp_addrinfo[1]; /**< Peer/own address info */
su_sockaddr_t tp_addr[1]; /**< Peer/own address */
#define tp_addrlen tp_addrinfo->ai_addrlen
#if HAVE_SOFIA_STUN
#if 0
stun_socket_t *tp_stun_socket;
#endif
su_socket_t tp_stun_socket;
#endif
/* ==== Receive queue ================================================== */
msg_t *tp_msg; /**< Message being received */
/* ==== Pending messages =============================================== */
tport_pending_t *tp_pending; /**< Pending requests */
tport_pending_t *tp_released; /**< Released pends */
unsigned tp_plen; /**< Size of tp_pending */
unsigned tp_pused; /**< Used pends */
unsigned tp_reported; /**< Report counter */
/* ==== Send queue ===================================================== */
msg_t **tp_queue; /**< Messages being sent */
unsigned short tp_qhead; /**< Head of queue */
msg_iovec_t *tp_unsent; /**< Pointer to first unsent iovec */
unsigned tp_unsentlen; /**< Number of unsent iovecs */
msg_iovec_t *tp_iov; /**< Iovecs allocated for sending */
unsigned tp_iovlen; /**< Number of allocated iovecs */
/* ==== Statistics ===================================================== */
struct {
uint64_t sent_bytes, sent_on_line, recv_bytes, recv_on_line;
uint64_t sent_msgs, recv_msgs;
} tp_stats;
};
/** Primary structure */
struct tport_primary {
tport_t pri_primary[1]; /**< Transport part */
#if DOX
su_home_t pri_home[1];
#else
#define pri_home pri_primary->tp_home
#define pri_master pri_primary->tp_master
#define pri_protoname pri_primary->tp_name->tpn_proto
#endif
tport_vtable_t const
*pri_vtable;
int pri_public; /**< Type of primary transport;
* tport_type_local,
* tport_type_stun, etc.
*/
char pri_ident[16];
tport_primary_t *pri_next; /**< Next primary tport */
tport_t *pri_secondary; /**< Secondary tports */
tport_threadpool_t *pri_threadpool; /**< Worker threads */
unsigned pri_thrpsize;
unsigned pri_natted:1; /**< Using natted address */
unsigned pri_has_tls:1; /**< Supports tls */
unsigned:0;
tport_params_t pri_params[1]; /**< Transport parameters */
};
/** Master structure */
struct tport_master {
tport_t mr_master[1];
#if DOX
su_home_t mr_home[1];
#else
#define mr_home mr_master->tp_home
#endif
int mr_stun_step_ready; /**< for stun's callback */
tp_stack_t *mr_stack; /**< Transport consumer */
tp_stack_class_t
const *mr_tpac; /**< Methods provided by stack */
int mr_log; /**< Do logging of parsed messages */
su_root_t *mr_root; /**< SU root pointer */
/**< Timer reclaiming unused connections and compartment */
su_timer_t *mr_timer;
/** File to dump received and sent data */
FILE *mr_dump_file;
tport_primary_t *mr_primaries; /**< List of primary contacts */
tport_params_t mr_params[1];
unsigned mr_boundserver:1; /**< Server has been bound */
unsigned mr_bindv6only:1; /**< We can bind separately to IPv6/4 */
unsigned :0;
#if HAVE_SIGCOMP
struct sigcomp_compartment *mr_compartment;
#endif
/* Delivery context */
struct tport_delivery {
tport_t *d_tport;
msg_t *d_msg;
tp_name_t d_from[1];
struct sigcomp_udvm **d_udvm;
} mr_delivery[1];
struct tport_nat_s {
int initialized;
int bound;
int stun_enabled;
char *external_ip_address;
#if HAVE_UPNP || HAVE_SOFIA_STUN
int try_stun;
#endif
#if HAVE_UPNP
#endif
#if HAVE_SOFIA_STUN
tport_master_t *tport;
char *stun_server;
/* stun_socket_t *stun_socket; */
stun_handle_t *stun;
su_socket_t stun_socket;
su_sockaddr_t sockaddr;
#endif
} mr_nat[1];
};
/** Virtual funtion table */
struct tport_vtable
{
char const *vtp_name;
enum tport_via vtp_public;
int vtp_pri_size; /* Size of primary tport */
int (*vtp_init_primary)(tport_primary_t *pri,
tp_name_t const tpn[1],
su_addrinfo_t *ai, tagi_t const *,
char const **return_culprit);
int (*vtp_init_compression)(tport_primary_t *self, char const *compression,
tagi_t const *tl);
void (*vtp_deinit_primary)(tport_primary_t *pri);
int (*vtp_wakeup_pri)(tport_primary_t *pri, int events);
tport_t *(*vtp_connect)(tport_primary_t *pri, su_addrinfo_t *ai,
tp_name_t const *tpn);
int vtp_secondary_size; /* Size of secondary tport */
int (*vtp_init_secondary)(tport_t *, int socket, int accepted);
void (*vtp_deinit_secondary)(tport_t *);
void (*vtp_shutdown)(tport_t *, int how);
int (*vtp_set_events)(tport_t const *self);
int (*vtp_wakeup)(tport_t *self, int events);
int (*vtp_recv)(tport_t *self);
int (*vtp_send)(tport_t const *self, msg_t *msg,
msg_iovec_t iov[], int iovused);
void (*vtp_deliver)(tport_t *self, msg_t *msg, su_time_t now);
int (*vtp_prepare)(tport_t *self, msg_t *msg,
tp_name_t const *tpn,
struct sigcomp_compartment *cc,
unsigned mtu);
};
/** Test if transport is needs connect() before sending. */
static inline int tport_is_connection_oriented(tport_t const *self)
{
return self->tp_conn_orient;
}
/** Test if transport has actual connection. */
static inline int tport_is_connected(tport_t const *self)
{
return self->tp_connected;
}
int tport_init_compression(tport_primary_t *pri,
char const *compression,
tagi_t const *tl);
tport_t *tport_alloc_secondary(tport_primary_t *pri, int socket, int accepted);
tport_t *tport_base_connect(tport_primary_t *pri,
su_addrinfo_t *ai,
su_addrinfo_t *name,
tp_name_t const *tpn);
int tport_accept(tport_primary_t *pri, int events);
void tport_zap_secondary(tport_t *self);
int tport_bind_socket(int socket,
su_addrinfo_t *ai,
char const **return_culprit);
void tport_close(tport_t *self);
int tport_error_event(tport_t *self);
void tport_recv_event(tport_t *self);
void tport_send_event(tport_t *self);
void tport_hup_event(tport_t *self);
int tport_recv_iovec(tport_t const *self,
msg_t **mmsg,
msg_iovec_t iovec[msg_n_fragments], int N,
int exact);
msg_t *tport_msg_alloc(tport_t const *self, unsigned size);
int tport_prepare_and_send(tport_t *self, msg_t *msg,
tp_name_t const *tpn,
struct sigcomp_compartment *cc,
unsigned mtu);
int tport_send_msg(tport_t *self, msg_t *msg,
tp_name_t const *tpn,
struct sigcomp_compartment *cc);
void tport_deliver(tport_t *self, msg_t *msg, msg_t *next,
struct sigcomp_udvm **pointer_to_udvm,
su_time_t now);
void tport_base_deliver(tport_t *self, msg_t *msg, su_time_t now);
int tport_recv_error_report(tport_t *self);
void tport_error_report(tport_t *self, int errcode,
su_sockaddr_t const *addr);
void tport_open_log(tport_master_t *mr, tagi_t *tags);
void tport_log_msg(tport_t *tp, msg_t *msg, char const *what,
char const *via, char const *indent, su_time_t now);
void tport_dump_iovec(tport_t const *self, msg_t *msg,
int n, su_iovec_t const iov[], int iovused,
char const *what, char const *how);
extern tport_vtable_t const * const tport_udp_vtable;
extern tport_vtable_t const * const tport_udp_client_vtable;
int tport_udp_init_primary(tport_primary_t *,
tp_name_t const tpn[1],
su_addrinfo_t *,
tagi_t const *,
char const **return_culprit);
int tport_recv_dgram(tport_t *self);
int tport_recv_dgram_r(tport_t const *self, msg_t **mmsg, int N);
int tport_send_dgram(tport_t const *self, msg_t *msg,
msg_iovec_t iov[], int iovused);
int tport_udp_error(tport_t const *self, su_sockaddr_t name[1]);
extern tport_vtable_t const * const tport_tcp_vtable;
extern tport_vtable_t const * const tport_tcp_client_vtable;
int tport_tcp_init_primary(tport_primary_t *,
tp_name_t const tpn[1],
su_addrinfo_t *, tagi_t const *,
char const **return_culprit);
int tport_tcp_init_client(tport_primary_t *,
tp_name_t const tpn[1],
su_addrinfo_t *, tagi_t const *,
char const **return_culprit);
int tport_tcp_init_secondary(tport_t *self, int socket, int accepted);
int tport_recv_stream(tport_t *self);
int tport_send_stream(tport_t const *self, msg_t *msg,
msg_iovec_t iov[], int iovused);
extern tport_vtable_t const * const tport_sctp_vtable;
extern tport_vtable_t const * const tport_sctp_client_vtable;
extern tport_vtable_t const * const tport_tls_vtable;
extern tport_vtable_t const * const tport_tls_client_vtable;
extern tport_vtable_t const * const tport_stun_vtable;
extern tport_vtable_t const * const tport_http_connect_vtable;
extern tport_vtable_t const * const tport_threadpool_vtable;
SOFIA_END_DECLS
#endif /* TPORT_INTERNAL_H */
/*
* This file is part of the Sofia-SIP package
*
* Copyright (C) 2006 Nokia Corporation.
*
* Contact: Pekka Pessi <pekka.pessi@nokia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
/**@CFILE tport_connect.c Transport using HTTP CONNECT.
*
* See tport.docs for more detailed description of tport interface.