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 diff is collapsed.
/*
* 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.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
* @author Martti Mela <Martti.Mela@nokia.com>
*
* @date Created: Fri Mar 24 08:45:49 EET 2006 ppessi
*/
#include "config.h"
#include "tport_internal.h"
#include <sofia-sip/string0.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#include <errno.h>
#include <limits.h>
/**@var TPORT_LOG
*
* Environment variable determining if parsed message contents are logged.
*
* If the TPORT_LOG environment variable is set, the tport module logs the
* contents of parsed messages. This eases debugging the signaling greatly.
*
* @sa TPORT_DUMP, TPORT_DEBUG, tport_log
*/
extern char const TPORT_LOG[]; /* dummy declaration for Doxygen */
/**@var TPORT_DUMP
*
* Environment variable for transport data dump.
*
* The received and sent data is dumped to the file specified by TPORT_DUMP
* environment variable. This can be used to save message traces and help
* hairy debugging tasks.
*
* @sa TPORT_LOG, TPORT_DEBUG, tport_log
*/
extern char const TPORT_DUMP[]; /* dummy declaration for Doxygen */
/**@var TPORT_DEBUG
*
* Environment variable determining the debug log level for @b tport module.
*
* The TPORT_DEBUG environment variable is used to determine the debug logging
* level for @b tport module. The default level is 3.
*
* @sa <su_debug.h>, tport_log, SOFIA_DEBUG
*/
extern char const TPORT_DEBUG[]; /* dummy declaration for Doxygen */
/**Debug log for @b tport module.
*
* The tport_log is the log object used by @b tport module. The level of
* #tport_log is set using #TPORT_DEBUG environment variable.
*/
su_log_t tport_log[] = {
SU_LOG_INIT("tport", "TPORT_DEBUG", SU_DEBUG)
};
/** Initialize logging. */
void tport_open_log(tport_master_t *mr, tagi_t *tags)
{
char const *log;
mr->mr_log =
getenv("MSG_STREAM_LOG") != NULL ||
getenv("TPORT_LOG") != NULL
? MSG_DO_EXTRACT_COPY : 0;
if ((log = getenv("TPORT_DUMP")) || (log = getenv("MSG_DUMP"))) {
time_t now;
if (strcmp(log, "-"))
mr->mr_dump_file = fopen(log, "ab"); /* XXX */
else
mr->mr_dump_file = stdout;
if (mr->mr_dump_file) {
time(&now);
fprintf(mr->mr_dump_file, "dump started at %s\n\n", ctime(&now));
}
}
}
/** Create log stamp */
void tport_stamp(tport_t const *self, msg_t *msg,
char stamp[128], char const *what,
int n, char const *via,
su_time_t now)
{
char label[24] = "";
char *comp = "";
char name[SU_ADDRSIZE] = "";
su_sockaddr_t const *su = msg_addr(msg);
unsigned short second, minute, hour;
second = (unsigned short)(now.tv_sec % 60);
minute = (unsigned short)((now.tv_sec / 60) % 60);
hour = (unsigned short)((now.tv_sec / 3600) % 24);
#if SU_HAVE_IN6
if (su->su_family == AF_INET6) {
if (su->su_sin6.sin6_flowinfo)
snprintf(label, sizeof(label), "/%u", ntohl(su->su_sin6.sin6_flowinfo));
}
#endif
if (msg_addrinfo(msg)->ai_flags & TP_AI_COMPRESSED)
comp = ";comp=sigcomp";
inet_ntop(su->su_family, SU_ADDR(su), name, sizeof(name));
snprintf(stamp, 128,
"%s %d bytes %s %s/[%s]:%u%s%s at %02u:%02u:%02u.%06lu:\n",
what, n, via, self->tp_name->tpn_proto,
name, ntohs(su->su_port), label[0] ? label : "", comp,
hour, minute, second, now.tv_usec);
}
/** Dump the data from the iovec */
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)
{
tport_master_t *mr = self->tp_master;
char stamp[128];
int i;
if (!mr->mr_dump_file)
return;
tport_stamp(self, msg, stamp, what, n, how, su_now());
fputs(stamp, mr->mr_dump_file);
for (i = 0; i < iovused && n > 0; i++) {
int len = iov[i].mv_len;
if (len > n)
len = n;
fwrite(iov[i].mv_base, len, 1, mr->mr_dump_file);
n -= len;
}
fputs("\v\n", mr->mr_dump_file);
fflush(mr->mr_dump_file);
}
/** Log the message. */
void tport_log_msg(tport_t *self, msg_t *msg,
char const *what, char const *via,
char const *first, su_time_t now)
{
char stamp[128];
msg_iovec_t iov[80];
int i, n, iovlen = msg_iovec(msg, iov, 80);
int skip_lf = 0, linelen = 0;
char const *prefix = first;
if (iovlen < 0) return;
for (i = n = 0; i < iovlen && i < 80; i++)
n += iov[i].mv_len;
tport_stamp(self, msg, stamp, what, n, via, now);
su_log(stamp);
for (i = 0; i < iovlen && i < 80; i++) {
char *s = iov[i].mv_base, *end = s + iov[i].mv_len;
int n;
if (skip_lf && s < end && s[0] == '\n') { s++; skip_lf = 0; }
while (s < end) {
if (s[0] == '\0') {
int j, len = s - (char *)iov[i].mv_base;
for (j = 0; j < i; j++)
len += iov[j].mv_len;
su_log("\n%s*** message truncated at %d\n", prefix, len);
return;
}
n = strncspn(s, end - s, "\r\n");
if (prefix) {
su_log("%s", prefix); linelen = n;
} else {
linelen += n;
}
su_log("%.*s", n, s);
if (s + n < end) {
su_log("\n");
prefix = first;
}
else {
prefix = "";
}
s += n;
/* Skip a eol */
if (s < end) {
if (s + 1 < end && s[0] == '\r' && s[1] == '\n')
s += 2;
else if (s[0] == '\r')
s++, (skip_lf = s + 1 == end);
else if (s[0] == '\n')
s++;
}
}
}
if (linelen) su_log("\n");
if (i == 80) {
int j, len = 0;
for (j = 0; j < i; j++)
len += iov[j].mv_len;
su_log("\n%s*** message truncated at %d\n", prefix, len);
return;
}
}
This diff is collapsed.
/*
* PLEASE NOTE:
*
* This file is automatically generated by tag_dll.awk.
* It contains tag_typedef_t for tag references.
*
* Do not, repeat, do not edit this file. Edit 'tport_tag.c' instead.
*
*/
#include "config.h"
#include <sofia-sip/su_tag_class.h>
#ifdef _WIN32
#define EXPORT __declspec(dllexport)
#else
#define EXPORT
#endif
#undef TAG_NAMESPACE
#define TAG_NAMESPACE "tp"
extern tag_typedef_t tptag_ident;
EXPORT tag_typedef_t tptag_ident_ref =
REFTAG_TYPEDEF(tptag_ident);
extern tag_typedef_t tptag_reuse;
EXPORT tag_typedef_t tptag_reuse_ref =
REFTAG_TYPEDEF(tptag_reuse);
extern tag_typedef_t tptag_fresh;
EXPORT tag_typedef_t tptag_fresh_ref =
REFTAG_TYPEDEF(tptag_fresh);
extern tag_typedef_t tptag_server;
EXPORT tag_typedef_t tptag_server_ref =
REFTAG_TYPEDEF(tptag_server);
extern tag_typedef_t tptag_public;
EXPORT tag_typedef_t tptag_public_ref =
REFTAG_TYPEDEF(tptag_public);
extern tag_typedef_t tptag_mtu;
EXPORT tag_typedef_t tptag_mtu_ref =
REFTAG_TYPEDEF(tptag_mtu);
extern tag_typedef_t tptag_connect;
EXPORT tag_typedef_t tptag_connect_ref =
REFTAG_TYPEDEF(tptag_connect);
extern tag_typedef_t tptag_sdwn_error;
EXPORT tag_typedef_t tptag_sdwn_error_ref =
REFTAG_TYPEDEF(tptag_sdwn_error);
extern tag_typedef_t tptag_sdwn_after;
EXPORT tag_typedef_t tptag_sdwn_after_ref =
REFTAG_TYPEDEF(tptag_sdwn_after);
extern tag_typedef_t tptag_close_after;
EXPORT tag_typedef_t tptag_close_after_ref =
REFTAG_TYPEDEF(tptag_close_after);
extern tag_typedef_t tptag_idle;
EXPORT tag_typedef_t tptag_idle_ref =
REFTAG_TYPEDEF(tptag_idle);
extern tag_typedef_t tptag_timeout;
EXPORT tag_typedef_t tptag_timeout_ref =
REFTAG_TYPEDEF(tptag_timeout);
extern tag_typedef_t tptag_sigcomp_lifetime;
EXPORT tag_typedef_t tptag_sigcomp_lifetime_ref =
REFTAG_TYPEDEF(tptag_sigcomp_lifetime);
extern tag_typedef_t tptag_certificate;
EXPORT tag_typedef_t tptag_certificate_ref =
REFTAG_TYPEDEF(tptag_certificate);
extern tag_typedef_t tptag_compartment;
EXPORT tag_typedef_t tptag_compartment_ref =
REFTAG_TYPEDEF(tptag_compartment);
extern tag_typedef_t tptag_tls_version;
EXPORT tag_typedef_t tptag_tls_version_ref =
REFTAG_TYPEDEF(tptag_tls_version);
extern tag_typedef_t tptag_queuesize;
EXPORT tag_typedef_t tptag_queuesize_ref =
REFTAG_TYPEDEF(tptag_queuesize);
extern tag_typedef_t tptag_debug_drop;
EXPORT tag_typedef_t tptag_debug_drop_ref =
REFTAG_TYPEDEF(tptag_debug_drop);
extern tag_typedef_t tptag_udp_rmem;
EXPORT tag_typedef_t tptag_udp_rmem_ref =
REFTAG_TYPEDEF(tptag_udp_rmem);
extern tag_typedef_t tptag_udp_wmem;
EXPORT tag_typedef_t tptag_udp_wmem_ref =
REFTAG_TYPEDEF(tptag_udp_wmem);
extern tag_typedef_t tptag_thrpsize;
EXPORT tag_typedef_t tptag_thrpsize_ref =
REFTAG_TYPEDEF(tptag_thrpsize);
extern tag_typedef_t tptag_thrprqsize;
EXPORT tag_typedef_t tptag_thrprqsize_ref =
REFTAG_TYPEDEF(tptag_thrprqsize);
extern tag_typedef_t tptag_http_connect;
EXPORT tag_typedef_t tptag_http_connect_ref =
REFTAG_TYPEDEF(tptag_http_connect);
This diff is collapsed.
/*
* 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_type_sctp.c Transport using SCTP.
*
* See tport.docs for more detailed description of tport interface.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
* @author Martti Mela <Martti.Mela@nokia.com>
*
* @date Created: Fri Mar 24 08:45:49 EET 2006 ppessi
* @date Original Created: Thu Jul 20 12:54:32 2000 ppessi
*/
#include "config.h"
#if HAVE_SCTP
#include "tport_internal.h"
#if HAVE_NETINET_SCTP_H
#include <netinet/sctp.h>
#undef HAVE_SCTP
#define HAVE_SCTP 1
#endif
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#include <errno.h>
#include <limits.h>
/* ---------------------------------------------------------------------- */
/* SCTP */
#define TP_SCTP_MSG_MAX (32768)
static int tport_sctp_init_primary(tport_primary_t *,
tp_name_t const tpn[1],
su_addrinfo_t *, tagi_t const *,
char const **return_culprit);
static int tport_sctp_init_client(tport_primary_t *,
tp_name_t const tpn[1],
su_addrinfo_t *, tagi_t const *,
char const **return_culprit);
static int tport_sctp_init_secondary(tport_t *self, int socket, int accepted);
static int tport_recv_sctp(tport_t *self);
static int tport_send_sctp(tport_t const *self, msg_t *msg,
msg_iovec_t iov[], int iovused);
tport_vtable_t const tport_sctp_client_vtable_ =
{
"sctp", tport_type_client,
sizeof (tport_primary_t),
tport_sctp_init_client,
NULL,
NULL,
tport_accept,
NULL,
sizeof (tport_t),
tport_sctp_init_secondary,
NULL,
NULL,
NULL,
NULL,
tport_recv_sctp,
tport_send_sctp,
};
#undef NEXT_VTABLE
#define NEXT_VTABLE &tport_sctp_client_vtable
tport_vtable_t const tport_sctp_vtable_ =
{
"sctp", tport_type_local,
sizeof (tport_primary_t),
tport_sctp_init_primary,
NULL,
NULL,
tport_accept,
NULL,
sizeof (tport_t),
tport_sctp_init_secondary,
NULL,
NULL,
NULL,
NULL,
tport_recv_sctp,
tport_send_sctp,
};
#undef NEXT_VTABLE
#define NEXT_VTABLE &tport_sctp_vtable
static int tport_sctp_init_primary(tport_primary_t *pri,
tp_name_t const tpn[1],
su_addrinfo_t *ai,
tagi_t const *tags,
char const **return_culprit)
{
if (pri->pri_params->tpp_mtu > TP_SCTP_MSG_MAX)
pri->pri_params->tpp_mtu = TP_SCTP_MSG_MAX;
return tport_tcp_init_primary(pri, tpn, ai, tags, return_culprit);
}
static int tport_sctp_init_client(tport_primary_t *pri,
tp_name_t const tpn[1],
su_addrinfo_t *ai,
tagi_t const *tags,
char const **return_culprit)
{
if (pri->pri_params->tpp_mtu > TP_SCTP_MSG_MAX)
pri->pri_params->tpp_mtu = TP_SCTP_MSG_MAX;
return tport_tcp_init_client(pri, tpn, ai, tags, return_culprit);
}
static int tport_sctp_init_secondary(tport_t *self, int socket, int accepted)
{
self->tp_connected = 1;
if (su_setblocking(socket, 0) < 0)
return -1;
return 0;
}
/** Receive data available on the socket.
*
* @retval -1 error
* @retval 0 end-of-stream
* @retval 1 normal receive
* @retval 2 incomplete recv, recv again
*/
static
int tport_recv_sctp(tport_t *self)
{
msg_t *msg;
int N, veclen, exact = 0, eos;
msg_iovec_t iovec[2] = {{ 0 }};
char sctp_buf[TP_SCTP_MSG_MAX];
iovec[0].mv_base = sctp_buf;
iovec[0].mv_len = sizeof(sctp_buf);
N = su_vrecv(self->tp_socket, iovec, 1, 0, NULL, NULL);
if (N == SOCKET_ERROR)
return tport_recv_error_report(self);
veclen = tport_recv_iovec(self, &self->tp_msg, iovec, N, exact = 1);
if (veclen < 0)
return -1;
assert(veclen == 1); assert(iovec[0].mv_len == N);
msg = self->tp_msg;
/* Message address */
*msg_addr(msg) = *self->tp_addr;
*msg_addrlen(msg) = su_sockaddr_size(self->tp_addr);
memcpy(iovec[0].mv_base, sctp_buf, iovec[0].mv_len);
if (self->tp_master->mr_dump_file)
tport_dump_iovec(self, msg, N, iovec, veclen, "recv", "from");
msg_recv_commit(msg, N, eos = 1); /* Mark buffer as used */
return 2;
}
static int tport_send_sctp(tport_t const *self, msg_t *msg,
msg_iovec_t iov[], int iovused)
{
return tport_send_dgram(self, msg, iov, iovused);
}
#endif
This diff is collapsed.
/*
* 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.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
* @author Martti Mela <Martti.Mela@nokia.com>
*
* @date Created: Fri Mar 24 08:45:49 EET 2006 ppessi
*/
#include "config.h"
#include "tport_internal.h"
#if HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#ifndef SOL_TCP
#define SOL_TCP IPPROTO_TCP
#endif
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#include <errno.h>
#include <limits.h>
/* ---------------------------------------------------------------------- */
/* TCP */
tport_vtable_t const tport_tcp_vtable_ =
{
"tcp", tport_type_local,
sizeof (tport_primary_t),
tport_tcp_init_primary,
tport_init_compression,
NULL,
tport_accept,
NULL,