Commit 31f5e43b authored by Pekka Pessi's avatar Pekka Pessi
Browse files

Added stun server and compression plugins.

Added TPORT_STUN_SERVER().
Having stun server dependencies in <tport_stub_stun.c>.
Moved sigcomp dependencies into <tport_stub_sigcomp.c>.

darcs-hash:20060331154135-88462-90caca9b5511bfdae6efa5d609deee9d03841607.gz
parent 11026cd3
......@@ -28,7 +28,8 @@ TESTS = test_tport
# Rules for building the targets
nobase_include_sofia_HEADERS = \
sofia-sip/tport.h sofia-sip/tport_tag.h
sofia-sip/tport.h sofia-sip/tport_tag.h \
sofia-sip/tport_plugins.h
TLS_SRC = tport_type_tls.c tport_tls.c tport_tls.h
......@@ -37,6 +38,7 @@ USE_TLS_SRC = $(TLS_SRC)
endif
libtport_la_SOURCES = tport.c tport_logging.c \
tport_stub_stun.c tport_stub_sigcomp.c \
tport_type_udp.c tport_type_tcp.c tport_type_sctp.c \
tport_type_connect.c tport_type_stun.c \
tport_threadpool.c tport_internal.h \
......
......@@ -169,26 +169,15 @@ typedef struct {
/** Create first primary transport. */
TPORT_DLL tport_t *tport_tcreate(tp_stack_t *stack,
tport_stack_class_t const *tpac,
su_root_t *root,
tag_type_t tag, tag_value_t value, ...);
/** Create first primary transport. @deprecated Use tport_tcreate(). */
TPORT_DLL tport_t *tport_create(tp_stack_t *stack,
tport_stack_class_t const *stack_class,
su_root_t *root);
/** Bind transports to network */
TPORT_DLL int tport_bind(tport_t *self,
tp_name_t const *tpn,
char const * const transports[],
int flags);
tport_stack_class_t const *tpac,
su_root_t *root,
tag_type_t tag, tag_value_t value, ...);
/** Bind transports to network. */
TPORT_DLL int tport_tbind(tport_t *self,
tp_name_t const *tpn,
char const * const transports[],
tag_type_t tag, tag_value_t value, ...);
tp_name_t const *tpn,
char const * const transports[],
tag_type_t tag, tag_value_t value, ...);
/** Get transport parameters. */
TPORT_DLL int tport_get_params(tport_t const *, tag_type_t tag, tag_value_t value, ...);
......@@ -208,12 +197,9 @@ TPORT_DLL tport_t *tport_incref(tport_t *tp);
/** Destroy a transport reference. */
TPORT_DLL void tport_decref(tport_t **tp);
/** Send a message using transport. @deprecated Use tport_tsend(). */
TPORT_DLL int tport_send(tport_t *, msg_t *, tp_name_t const *);
/** Send a message using transport. */
TPORT_DLL tport_t *tport_tsend(tport_t *, msg_t *, tp_name_t const *,
tag_type_t, tag_value_t, ...);
tag_type_t, tag_value_t, ...);
/** Queue a message to transport. */
TPORT_DLL int tport_tqueue(tport_t *, msg_t *, tag_type_t, tag_value_t, ...);
......@@ -222,7 +208,8 @@ TPORT_DLL int tport_tqueue(tport_t *, msg_t *, tag_type_t, tag_value_t, ...);
TPORT_DLL int tport_queuelen(tport_t const *self);
/** Send a queued message (and queue another, if required). */
TPORT_DLL int tport_tqsend(tport_t *, msg_t *, msg_t *, tag_type_t, tag_value_t, ...);
TPORT_DLL int tport_tqsend(tport_t *, msg_t *, msg_t *,
tag_type_t, tag_value_t, ...);
/** Stop reading from socket until tport_continue() is called. */
TPORT_DLL int tport_stall(tport_t *self);
......@@ -349,6 +336,10 @@ int tport_keepalive(tport_t *tp, su_addrinfo_t const *ai,
/* ---------------------------------------------------------------------- */
/* SigComp-related functions */
TPORT_DLL
struct sigcomp_compartment *tport_init_comp(tport_t *self,
char const *algorithm_name);
TPORT_DLL int tport_can_send_sigcomp(tport_t const *self);
TPORT_DLL int tport_can_recv_sigcomp(tport_t const *self);
......@@ -356,7 +347,8 @@ TPORT_DLL int tport_has_compression(tport_t const *self, char const *comp);
TPORT_DLL int tport_set_compression(tport_t *self, char const *comp);
/** Set SigComp option. */
TPORT_DLL int tport_sigcomp_option(tport_t const *self,
TPORT_DLL
int tport_sigcomp_option(tport_t const *self,
struct sigcomp_compartment *cc,
char const *option);
......
/*
* 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_PLUGINS_H
/** Defined when <sofia-sip/tport_plugins.h> has been included. */
#define TPORT_PLUGINS_H
/**@file tport_plugins.h
* @brief Transport plugin interface
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
*
* @date Created: Fri Mar 31 12:22:22 EEST 2006 ppessi
*/
/* -- STUN Plugin ------------------------------------------------------- */
#ifndef TPORT_STUN_SERVER_T
#define TPORT_STUN_SERVER_T struct tport_stun_server_s
#endif
/** Safe type for tport server object */
typedef TPORT_STUN_SERVER_T tport_stun_server_t;
typedef struct {
int vst_size;
tport_stun_server_t *(*vst_create)(su_root_t *root, tagi_t const *tags);
void (*vst_destroy)(tport_stun_server_t *);
int (*vst_add_socket)(tport_stun_server_t *, int socket);
int (*vst_remove_socket)(tport_stun_server_t *, int socket);
void (*vst_request)(tport_stun_server_t *server, int socket,
void *msg, ssize_t msglen,
void *addr, socklen_t addrlen);
} tport_stun_server_vtable_t;
SOFIAPUBFUN int tport_plug_in_stun_server(tport_stun_server_vtable_t const *);
/* -- SigComp Plugin ---------------------------------------------------- */
#ifndef TPORT_COMP_T
#define TPORT_COMP_T struct tport_compress
#endif
typedef TPORT_COMP_T tport_comp_t;
/* We already use these SigComp types in applications */
struct sigcomp_udvm;
struct sigcomp_compartment;
typedef struct tport_comp_vtable_s tport_comp_vtable_t;
SOFIAPUBFUN int tport_plug_in_comp(tport_comp_vtable_t const *);
#endif /* !defined(TPORT_PLUGINS_H) */
......@@ -249,6 +249,13 @@ TPORT_DLL extern tag_typedef_t tptag_http_connect;
TPORT_DLL extern tag_typedef_t tptag_http_connect_ref;
#define TPTAG_HTTP_CONNECT_REF(x) tptag_http_connect_ref, tag_str_vr(&(x))
TPORT_DLL extern tag_typedef_t tptag_stun_server;
/** Enable STUN server. */
#define TPTAG_STUN_SERVER(x) tptag_stun_server, tag_bool_v((x))
TPORT_DLL extern tag_typedef_t tptag_stun_server_ref;
#define TPTAG_STUN_SERVER_REF(x) tptag_stun_server_ref, tag_bool_vr(&(x))
SOFIA_END_DECLS
#endif /* !defined TPORT_TAG_H */
......@@ -352,7 +352,6 @@ static void tp_test_recv(tp_test_t *tt,
tp_magic_t *magic,
su_time_t now)
{
#if HAVE_SIGCOMP
tp_name_t frm[1];
if (tport_delivered_from(tp, msg, frm) != -1 && frm->tpn_comp) {
......@@ -360,7 +359,6 @@ static void tp_test_recv(tp_test_t *tt,
tport_sigcomp_accept(tp, cc, msg);
}
#endif
tt->tt_status = 1;
tt->tt_received++;
......@@ -966,6 +964,9 @@ static int sctp_test(tp_test_t *tt)
if (!tt->tt_sctp_name->tpn_proto)
return 0;
if (1)
return 0; /* SCTP does not work. */
/* Just a small and nice message first */
TEST_1(!new_test_msg(tt, &msg, "sctp-small", 1, 1024));
test_create_md5(tt, msg);
......
......@@ -311,9 +311,6 @@ int tport_has_sigcomp(tport_t const *self)
return self->tp_name->tpn_comp != NULL;
}
int tport_master_set_compartment(tport_master_t *mr,
struct sigcomp_compartment *cc);
static
tport_t *tport_connect(tport_primary_t *pri, su_addrinfo_t *ai,
tp_name_t const *tpn);
......@@ -368,8 +365,6 @@ static int
tport_pending_error(tport_t *self, su_sockaddr_t const *dst, int error),
tport_pending_errmsg(tport_t *self, msg_t *msg, int error);
void tport_try_accept_sigcomp(tport_t *self, msg_t *msg);
tport_t *tport_by_addrinfo(tport_primary_t const *pri,
su_addrinfo_t const *ai,
tp_name_t const *tpn);
......@@ -466,6 +461,7 @@ tport_t *tport_tcreate(tp_stack_t *stack,
tpp->tpp_idle = UINT_MAX;
tpp->tpp_timeout = UINT_MAX;
tpp->tpp_sigcomp_lifetime = UINT_MAX;
tpp->tpp_stun_server = 1;
tpn = mr->mr_master->tp_name;
tpn->tpn_proto = "*";
......@@ -486,6 +482,8 @@ tport_t *tport_tcreate(tp_stack_t *stack,
if (tick < 200)
tick = 200;
tport_init_stun_server(mr, ta_args(ta));
mr->mr_timer = su_timer_create(su_root_task(root), tick);
su_timer_set(mr->mr_timer, tport_tick, mr);
......@@ -523,10 +521,8 @@ void tport_destroy(tport_t *self)
while (mr->mr_primaries)
tport_zap_primary(mr->mr_primaries);
#if HAVE_SIGCOMP
if (mr->mr_compartment)
sigcomp_compartment_unref(mr->mr_compartment), mr->mr_compartment = NULL;
#endif
tport_deinit_comp(mr);
tport_deinit_stun_server(mr);
if (mr->mr_dump_file)
fclose(mr->mr_dump_file), mr->mr_dump_file = NULL;
......@@ -537,6 +533,7 @@ void tport_destroy(tport_t *self)
su_home_zap(mr->mr_home);
}
/** Allocate a primary transport */
static
tport_primary_t *tport_alloc_primary(tport_master_t *mr,
......@@ -999,6 +996,8 @@ void tport_zap_secondary(tport_t *self)
mr = self->tp_master;
tport_stun_server_remove_socket(self);
if (self->tp_index)
su_root_deregister(mr->mr_root, self->tp_index);
self->tp_index = 0;
......@@ -1085,7 +1084,7 @@ int tport_set_params(tport_t *self,
int n;
tport_params_t tpp[1], *tpp0;
int connect, sdwn_error, reusable, public = 0;
int connect, sdwn_error, reusable, stun_server;
struct sigcomp_compartment *cc = NONE;
......@@ -1097,6 +1096,7 @@ int tport_set_params(tport_t *self,
connect = tpp->tpp_conn_orient;
sdwn_error = tpp->tpp_sdwn_error;
reusable = self->tp_reusable;
stun_server = tpp->tpp_stun_server;
ta_start(ta, tag, value);
......@@ -1113,7 +1113,7 @@ int tport_set_params(tport_t *self,
TPTAG_SDWN_ERROR_REF(sdwn_error),
TPTAG_REUSE_REF(reusable),
TPTAG_COMPARTMENT_REF(cc),
TPTAG_PUBLIC_REF(public),
TPTAG_STUN_SERVER_REF(stun_server),
TAG_END());
ta_end(ta);
......@@ -1134,24 +1134,18 @@ int tport_set_params(tport_t *self,
if (tpp->tpp_qsize >= 1000)
tpp->tpp_qsize = 1000;
tpp->tpp_sdwn_error = sdwn_error;
self->tp_reusable = reusable;
/* Currently only primary UDP transport can *not* be connection oriented */
tpp->tpp_conn_orient = connect
|| !tport_is_primary(self) || !tport_is_dgram(self);
tpp->tpp_sdwn_error = sdwn_error;
self->tp_reusable = reusable;
tpp->tpp_stun_server = stun_server;
if (tport_is_secondary(self) &&
self->tp_params == self->tp_pri->pri_primary->tp_params) {
tpp0 = su_zalloc(self->tp_home, sizeof *tpp0); if (!tpp0) return -1;
}
if (cc != NONE && tport_is_master(self)) {
tport_master_set_compartment(self->tp_master, cc);
}
memcpy(tpp0, tpp, sizeof *tpp);
return n;
......@@ -1177,7 +1171,7 @@ tport_vtable_t const *tport_vtables[TPORT_NUMBER_OF_TYPES + 1] =
&tport_tls_client_vtable,
&tport_tls_vtable,
#endif
#if HAVE_SCTP
#if HAVE_SCTP && 0 /* SCTP is broken */
&tport_sctp_client_vtable,
&tport_sctp_vtable,
#endif
......@@ -1191,6 +1185,22 @@ tport_vtable_t const *tport_vtables[TPORT_NUMBER_OF_TYPES + 1] =
#endif
};
/** Register new transport vtable */
int tport_register_type(tport_vtable_t const *vtp)
{
int i;
for (i = TPORT_NUMBER_OF_TYPES; i >= 0; i--) {
if (tport_vtables[i] == NULL) {
tport_vtables[i] = vtp;
return 0;
}
}
su_seterrno(ENOMEM);
return -1;
}
/**Get a vtable for given protocol */
tport_vtable_t const *tport_vtable_by_name(char const *protoname,
enum tport_via public)
......@@ -1216,14 +1226,43 @@ tport_vtable_t const *tport_vtable_by_name(char const *protoname,
return NULL;
}
char const tport_sigcomp_name[] = "sigcomp";
#if 0
tport_set_f const *tport_set_methods[TPORT_NUMBER_OF_TYPES + 1] =
{
tport_server_bind_set,
tport_client_bind_set,
tport_threadpool_set,
tport_http_connect_set,
#if HAVE_TLS
tport_tls_set,
#endif
NULL
};
char const *tport_canonize_comp(char const *comp)
int tport_bind_set(tport_master_t *mr,
tp_name_t const *tpn,
char const * const transports[],
tagi_t const *taglist,
tport_set_t **return_set,
int set_size)
{
if (comp && strcasecmp(comp, tport_sigcomp_name) == 0)
return tport_sigcomp_name;
return NULL;
int i;
for (i = TPORT_NUMBER_OF_TYPES; i >= 0; i--) {
tport_set_f const *perhaps = tport_vtables[i];
int result;
if (perhaps == NULL)
continue;
result = perhaps(mr, tpn, transports, taglist, return_set, set_size);
if (result != 0)
return result;
}
return 0;
}
#endif
/** Bind transport objects.
*
......@@ -1283,6 +1322,7 @@ int tport_tbind(tport_t *self,
return retval;
}
/** Bind primary transport objects used by a client-only application.
* @internal
*/
......@@ -2632,11 +2672,7 @@ static void tport_parse(tport_t *self, int complete, su_time_t now)
else
next = NULL;
#if HAVE_SIGCOMP
tport_deliver(self, msg, next, &self->tp_sigcomp->sc_udvm, now);
#else
tport_deliver(self, msg, next, NULL, now);
#endif
tport_deliver(self, msg, next, tport_get_udvm_slot(self), now);
if (streaming && next == NULL)
break;
......@@ -2653,7 +2689,7 @@ static void tport_parse(tport_t *self, int complete, su_time_t now)
/** Deliver message to the protocol stack */
void tport_deliver(tport_t *self, msg_t *msg, msg_t *next,
struct sigcomp_udvm **pointer_to_udvm,
struct sigcomp_udvm **in_out_udvm,
su_time_t now)
{
tport_t *ref;
......@@ -2666,7 +2702,7 @@ void tport_deliver(tport_t *self, msg_t *msg, msg_t *next,
d->d_tport = self;
d->d_msg = msg;
d->d_udvm = pointer_to_udvm;
d->d_udvm = in_out_udvm;
*d->d_from = *self->tp_name;
if (tport_is_primary(self)) {
......@@ -2690,9 +2726,7 @@ void tport_deliver(tport_t *self, msg_t *msg, msg_t *next,
d->d_from->tpn_host = ipaddr;
}
#if HAVE_SIGCOMP
if (!pointer_to_udvm && !*pointer_to_udvm)
#endif
if (!in_out_udvm || !*in_out_udvm)
d->d_from->tpn_comp = NULL;
error = msg_has_error(msg);
......@@ -2760,20 +2794,20 @@ int tport_delivered_from(tport_t *tp, msg_t const *msg, tp_name_t name[1])
/** Return UDVM used to decompress the message. */
int
tport_delivered_using_udvm(tport_t *tp, msg_t const *msg,
struct sigcomp_udvm **return_pointer_to_udvm,
struct sigcomp_udvm **return_udvm,
int remove)
{
if (tp == NULL || msg == NULL || msg != tp->tp_master->mr_delivery->d_msg)
return -1;
if (return_pointer_to_udvm) {
if (return_udvm) {
if (tp->tp_master->mr_delivery->d_udvm) {
*return_pointer_to_udvm = *tp->tp_master->mr_delivery->d_udvm;
*return_udvm = *tp->tp_master->mr_delivery->d_udvm;
if (remove)
tp->tp_master->mr_delivery->d_udvm = NULL;
}
else {
*return_pointer_to_udvm = NULL;
*return_udvm = NULL;
}
}
......@@ -2992,10 +3026,8 @@ tport_t *tport_tsend(tport_t *self,
tpn->tpn_proto = self->tp_protoname;
#if HAVE_SIGCOMP
if (!cc)
tpn->tpn_comp = NULL;
#endif
/* Create a secondary transport which is connected to the destination */
self = tport_connect(primary, msg_addrinfo(msg), tpn);
......@@ -3010,27 +3042,13 @@ tport_t *tport_tsend(tport_t *self,
return NULL;
}
#if HAVE_SIGCOMP
if (cc)
tport_sigcomp_assign(self, cc);
#endif
}
}
#if HAVE_SIGCOMP
else if (tport_is_secondary(self)) {
if (self->tp_name->tpn_comp) {
if (cc)
tport_sigcomp_assign(self, cc);
else if (self->tp_sigcomp->sc_cc)
cc = self->tp_sigcomp->sc_cc;
else
/* Use default compartment */
cc = self->tp_master->mr_compartment;
}
else
cc = NULL;
cc = tport_sigcomp_assign_if_needed(self, cc);
}
#endif
if (cc == NULL)
tpn->tpn_comp = NULL;
......@@ -3190,12 +3208,13 @@ int tport_vsend(tport_t *self,
int n;
su_addrinfo_t *ai = msg_addrinfo(msg);
#if 0
n = tport_send_sigcomp(self, msg, iov, iovused, cc, self->tp_sigcomp);
#else
ai->ai_flags &= ~TP_AI_COMPRESSED;
n = self->tp_pri->pri_vtable->vtp_send(self, msg, iov, iovused);
#endif
if (cc) {
n = tport_send_comp(self, msg, iov, iovused, cc, self->tp_comp);
}
else {
ai->ai_flags &= ~TP_AI_COMPRESSED;
n = self->tp_pri->pri_vtable->vtp_send(self, msg, iov, iovused);
}
if (n == 0)
return 0;
......@@ -4452,76 +4471,3 @@ char *tport_hostport(char buf[], int bufsize,
}
/* ---------------------------------------------------------------------- */
int tport_master_set_compartment(tport_master_t *mr,
struct sigcomp_compartment *cc)
{
return 0;
}
int tport_init_compression(tport_primary_t *pri,
char const *compression,
tagi_t const *tl)
{
return 0;
}
int tport_sigcomp_assign(tport_t *self, struct sigcomp_compartment *cc)
{
return 0;
}
/** Test if tport has a SigComp compartment assigned to it. */
int tport_has_sigcomp_assigned(tport_t const *self)
{
return 0;
}
int
tport_sigcomp_accept(tport_t *self,
struct sigcomp_compartment *cc,
msg_t *msg)
{
return 0;
}
void tport_try_accept_sigcomp(tport_t *self,
msg_t *msg)
{
}
int tport_can_recv_sigcomp(tport_t const *self)
{
return 0;
}
int tport_can_send_sigcomp(tport_t const *self)
{
return 0;
}
int tport_has_compression(tport_t const *self, char const *comp)
{
return 0;
}
int tport_set_compression(tport_t *self, char const *comp)
{
return (self == NULL || comp) ? -1 : 0;
}
int tport_keepalive(tport_t *tp, su_addrinfo_t const *ai,
tag_type_t tag, tag_value_t value, ...)
{
if (tp && tp->tp_pri && tp->tp_pri->pri_vtable->vtp_keepalive) {
int retval;
ta_list ta;
ta_start(ta, tag, value);
retval = tp->tp_pri->pri_vtable->vtp_keepalive(tp, ai, ta_args(ta));
ta_end(ta);
return retval;
}
return -1;
}
......@@ -24,6 +24,7 @@
#ifndef TPORT_INTERNAL_H /** Defined when <tport.h> has been included. */
#define TPORT_INTERNAL_H
/**@file tport_internal.h