Freeswitch-svn
Threads by month
- ----- 2026 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
February 2009
- 20 participants
- 764 discussions
[commit] r11836 - in freeswitch/trunk/libs/sofia-sip: . libsofia-sip-ua/nua
by FreeSWITCH SVN 11 Feb '09
by FreeSWITCH SVN 11 Feb '09
11 Feb '09
Author: mikej
Date: Wed Feb 11 11:08:41 2009
New Revision: 11836
Log:
Fri Jan 16 13:37:43 CST 2009 Pekka Pessi <first.last(a)nokia.com>
* nua: fixed problem handling re-SUBSCRIBE when it creates new dialog
Modified:
freeswitch/trunk/libs/sofia-sip/.update
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/check_nua.c
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/check_nua.h
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/check_register.c
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/check_session.c
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/test_s2.c
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/test_s2.h
Modified: freeswitch/trunk/libs/sofia-sip/.update
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/.update (original)
+++ freeswitch/trunk/libs/sofia-sip/.update Wed Feb 11 11:08:41 2009
@@ -1 +1 @@
-Wed Feb 11 11:07:52 CST 2009
+Wed Feb 11 11:08:29 CST 2009
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/check_nua.c
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/check_nua.c (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/check_nua.c Wed Feb 11 11:08:41 2009
@@ -43,6 +43,8 @@
#include <fnmatch.h>
#endif
+#include "test_s2.h"
+
static char const * const default_patterns[] = { "*", NULL };
static char const * const *test_patterns = default_patterns;
@@ -80,6 +82,10 @@
Suite *suite = suite_create("Unit tests for Sofia-SIP UA Engine");
SRunner *runner;
+ s2_tester = "check_nua";
+ if (getenv("CHECK_NUA_VERBOSE"))
+ s2_start_stop = strtoul(getenv("CHECK_NUA_VERBOSE"), NULL, 10);
+
if (getenv("CHECK_NUA_CASES")) {
size_t i;
char *s, **patterns;
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/check_nua.h
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/check_nua.h (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/check_nua.h Wed Feb 11 11:08:41 2009
@@ -10,6 +10,7 @@
void check_session_cases(Suite *suite);
void check_register_cases(Suite *suite);
+void check_simple_cases(Suite *suite);
#endif
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/check_register.c
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/check_register.c (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/check_register.c Wed Feb 11 11:08:41 2009
@@ -54,12 +54,13 @@
static void register_setup(void)
{
- nua = s2_nua_setup(TAG_END());
+ nua = s2_nua_setup("register", TAG_END());
}
static void register_pingpong_setup(void)
{
- nua = s2_nua_setup(TPTAG_PINGPONG(20000),
+ nua = s2_nua_setup("register with pingpong",
+ TPTAG_PINGPONG(20000),
TPTAG_KEEPALIVE(10000),
TAG_END());
tport_set_params(s2->tcp.tport, TPTAG_PONG2PING(1), TAG_END());
@@ -68,6 +69,7 @@
static void register_teardown(void)
{
+ s2_teardown_started("register");
nua_shutdown(nua);
fail_unless(s2_check_event(nua_r_shutdown, 200));
s2_nua_teardown();
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/check_session.c
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/check_session.c (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/check_session.c Wed Feb 11 11:08:41 2009
@@ -63,9 +63,8 @@
static void call_setup(void)
{
- s2_case("0.1.1", "Setup for Call Tests", "");
-
- nua = s2_nua_setup(SIPTAG_ORGANIZATION_STR("Pussy Galore's Flying Circus"),
+ nua = s2_nua_setup("call",
+ SIPTAG_ORGANIZATION_STR("Pussy Galore's Flying Circus"),
NUTAG_OUTBOUND("no-options-keepalive, no-validate"),
TAG_END());
@@ -85,7 +84,7 @@
static void call_teardown(void)
{
- s2_case("0.1.2", "Teardown Call Test Setup", "");
+ s2_teardown_started("call");
mark_point();
@@ -3078,6 +3077,7 @@
static void options_teardown(void)
{
+ s2_teardown_started("options");
call_teardown();
}
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c Wed Feb 11 11:08:41 2009
@@ -1973,8 +1973,7 @@
static void nua_client_request_destroy(nua_client_request_t *cr);
static int nua_client_init_request0(nua_client_request_t *cr);
static int nua_client_request_try(nua_client_request_t *cr);
-static int nua_client_request_sendmsg(nua_client_request_t *cr,
- msg_t *msg, sip_t *sip);
+static int nua_client_request_sendmsg(nua_client_request_t *cr);
static void nua_client_restart_after(su_root_magic_t *magic,
su_timer_t *timer,
nua_client_request_t *cr);
@@ -2416,23 +2415,6 @@
(sip_header_t *)sip->sip_from) < 0) {
return nua_client_return(cr, NUA_ERROR_AT(__FILE__, __LINE__), msg);
}
-
- if (cr->cr_dialog) {
- ds->ds_leg = nta_leg_tcreate(nua->nua_nta,
- nua_stack_process_request, nh,
- SIPTAG_CALL_ID(sip->sip_call_id),
- SIPTAG_FROM(sip->sip_from),
- SIPTAG_TO(sip->sip_to),
- SIPTAG_CSEQ(sip->sip_cseq),
- TAG_END());
- if (!ds->ds_leg)
- return nua_client_return(cr, NUA_ERROR_AT(__FILE__, __LINE__), msg);
-
- if (!sip->sip_from->a_tag &&
- sip_from_tag(msg_home(msg), sip->sip_from,
- nta_leg_tag(ds->ds_leg, NULL)) < 0)
- return nua_client_return(cr, NUA_ERROR_AT(__FILE__, __LINE__), msg);
- }
}
else {
if (ds->ds_route)
@@ -2540,15 +2522,17 @@
if (nua_client_request_queue(cr))
return 0;
+
if (nua_dialog_is_reporting(cr->cr_owner->nh_ds))
return 0;
+
return nua_client_request_try(cr);
}
return 0;
}
-/** Create a request message and send it.
+/** Send a request message.
*
* If an error occurs, send error event to the application.
*
@@ -2558,26 +2542,11 @@
static
int nua_client_request_try(nua_client_request_t *cr)
{
- int error = -1;
- msg_t *msg = msg_copy(cr->cr_msg);
- sip_t *sip = sip_object(msg);
-
- cr->cr_answer_recv = 0, cr->cr_offer_sent = 0;
- cr->cr_offer_recv = 0, cr->cr_answer_sent = 0;
-
- if (msg && sip) {
- error = nua_client_request_sendmsg(cr, msg, sip);
- if (!error)
- return 0;
-
- if (error == -1)
- msg_destroy(msg);
- }
+ int error = nua_client_request_sendmsg(cr);
if (error < 0)
error = nua_client_response(cr, NUA_ERROR_AT(__FILE__, __LINE__), NULL);
- assert(error > 0);
return error;
}
@@ -2585,13 +2554,10 @@
*
* @retval 0 if request is pending
* @retval >=1 if error event has been sent
- * @retval -1 if error occurred but event has not been sent,
- and @a msg has not been destroyed
- * @retval -2 if error occurred, event has not been sent,
- * but @a msg has been destroyed
+ * @retval < 0 if no error event has been sent
*/
static
-int nua_client_request_sendmsg(nua_client_request_t *cr, msg_t *msg, sip_t *sip)
+int nua_client_request_sendmsg(nua_client_request_t *cr)
{
nua_handle_t *nh = cr->cr_owner;
nua_dialog_state_t *ds = nh->nh_ds;
@@ -2599,9 +2565,36 @@
char const *name = cr->cr_method_name;
url_string_t const *url = (url_string_t *)cr->cr_target;
nta_leg_t *leg;
+ msg_t *msg;
+ sip_t *sip;
+ int error;
assert(cr->cr_orq == NULL);
+ cr->cr_offer_sent = cr->cr_answer_recv = 0;
+ cr->cr_offer_recv = cr->cr_answer_sent = 0;
+
+ if (!ds->ds_leg && cr->cr_dialog) {
+ ds->ds_leg = nta_leg_tcreate(nh->nh_nua->nua_nta,
+ nua_stack_process_request, nh,
+ SIPTAG_CALL_ID(cr->cr_sip->sip_call_id),
+ SIPTAG_FROM(cr->cr_sip->sip_from),
+ SIPTAG_TO(cr->cr_sip->sip_to),
+ SIPTAG_CSEQ(cr->cr_sip->sip_cseq),
+ TAG_END());
+ if (!ds->ds_leg)
+ return -1;
+ }
+
+ if (cr->cr_sip->sip_from && ds->ds_leg) {
+ if (cr->cr_sip->sip_from->a_tag == NULL) {
+ if (sip_from_tag(msg_home(cr->cr_msg), cr->cr_sip->sip_from,
+ nta_leg_tag(ds->ds_leg, NULL)) < 0) {
+ return -1;
+ }
+ }
+ }
+
cr->cr_retry_count++;
if (ds->ds_leg)
@@ -2609,6 +2602,11 @@
else
leg = nh->nh_nua->nua_dhandle->nh_ds->ds_leg; /* Default leg */
+ msg = msg_copy(cr->cr_msg), sip = sip_object(msg);
+
+ if (msg == NULL)
+ return -1;
+
if (nua_dialog_is_established(ds)) {
while (sip->sip_route)
sip_route_remove(msg, sip);
@@ -2639,8 +2637,10 @@
* generated based on the dialog information and added to the request.
* If the dialog has a route, it is added to the request, too.
*/
- if (nta_msg_request_complete(msg, leg, method, name, url) < 0)
+ if (nta_msg_request_complete(msg, leg, method, name, url) < 0) {
+ msg_destroy(msg);
return -1;
+ }
/**@MaxForwards header (with default value set by NTATAG_MAX_FORWARDS()) is
* also added now, if it does not exist.
@@ -2716,16 +2716,23 @@
cr->cr_contactize &&
!cr->cr_has_contact &&
!ds->ds_ltarget,
- !ds->ds_route) < 0)
+ !ds->ds_route) < 0) {
+ msg_destroy(msg);
return -1;
+ }
}
cr->cr_wait_for_cred = 0;
if (cr->cr_methods->crm_send)
- return cr->cr_methods->crm_send(cr, msg, sip, NULL);
+ error = cr->cr_methods->crm_send(cr, msg, sip, NULL);
+ else
+ error = nua_base_client_request(cr, msg, sip, NULL);
- return nua_base_client_request(cr, msg, sip, NULL);
+ if (error != 0 && error != -2)
+ msg_destroy(msg);
+
+ return error;
}
/**Add tags to request message and send it,
@@ -2793,9 +2800,10 @@
}
/** Callback for nta client transaction */
-int nua_client_orq_response(nua_client_request_t *cr,
- nta_outgoing_t *orq,
- sip_t const *sip)
+int
+nua_client_orq_response(nua_client_request_t *cr,
+ nta_outgoing_t *orq,
+ sip_t const *sip)
{
int status;
char const *phrase;
@@ -3090,11 +3098,8 @@
int status, char const *phrase)
{
nua_handle_t *nh = cr->cr_owner;
- nua_dialog_state_t *ds = nh->nh_ds;
nta_outgoing_t *orq;
int error = -1, terminated, graceful;
- msg_t *msg = NULL;
- sip_t *sip = NULL;
if (cr->cr_retry_count > NH_PGET(nh, retry_count))
return 0;
@@ -3102,32 +3107,10 @@
orq = cr->cr_orq, cr->cr_orq = NULL; assert(orq);
terminated = cr->cr_terminated, cr->cr_terminated = 0;
graceful = cr->cr_graceful, cr->cr_graceful = 0;
- cr->cr_offer_sent = cr->cr_answer_recv = 0;
- cr->cr_offer_recv = cr->cr_answer_sent = 0;
- if (!ds->ds_leg && cr->cr_dialog) {
- sip_t const *sip = cr->cr_sip;
- ds->ds_leg = nta_leg_tcreate(nh->nh_nua->nua_nta,
- nua_stack_process_request, nh,
- SIPTAG_CALL_ID(sip->sip_call_id),
- SIPTAG_FROM(sip->sip_from),
- SIPTAG_TO(sip->sip_to),
- SIPTAG_CSEQ(sip->sip_cseq),
- TAG_END());
- }
-
- if (ds->ds_leg || !cr->cr_dialog) {
- msg = msg_copy(cr->cr_msg);
- sip = sip_object(msg);
- }
-
- if (msg && sip) {
- cr->cr_restarting = 1;
- error = nua_client_request_sendmsg(cr, msg, sip);
- cr->cr_restarting = 0;
- if (error !=0 && error != -2)
- msg_destroy(msg);
- }
+ cr->cr_restarting = 1;
+ error = nua_client_request_sendmsg(cr);
+ cr->cr_restarting = 0;
if (error) {
cr->cr_graceful = graceful;
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/test_s2.c
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/test_s2.c (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/test_s2.c Wed Feb 11 11:08:41 2009
@@ -52,6 +52,9 @@
#include <limits.h>
#include <time.h>
+char const *s2_tester = "s2_tester";
+int s2_start_stop;
+
/* -- Module types ------------------------------------------------------ */
struct tp_magic_s
@@ -207,6 +210,19 @@
return retval;
}
+int s2_check_substate(struct event *e, enum nua_substate state)
+{
+ int retval = 0;
+ tagi_t const *tagi;
+
+ tagi = tl_find(e->data->e_tags, nutag_substate);
+ if (tagi) {
+ retval = (tag_value_t)state == tagi->t_value;
+ }
+
+ return retval;
+}
+
static void
s2_nua_callback(nua_event_t event,
int status, char const *phrase,
@@ -371,6 +387,22 @@
return m != NULL;
}
+void
+s2_save_uas_dialog(struct dialog *d, sip_t *sip)
+{
+ if (d && !d->local) {
+ assert(sip->sip_request);
+ d->local = sip_from_dup(d->home, sip->sip_to);
+ if (d->local->a_tag == NULL)
+ sip_from_tag(d->home, d->local, s2_generate_tag(d->home));
+ d->remote = sip_to_dup(d->home, sip->sip_from);
+ d->call_id = sip_call_id_dup(d->home, sip->sip_call_id);
+ d->rseq = sip->sip_cseq->cs_seq;
+ /* d->route = sip_route_dup(d->home, sip->sip_record_route); */
+ d->target = sip_contact_dup(d->home, sip->sip_contact);
+ }
+}
+
struct message *
s2_respond_to(struct message *m, struct dialog *d,
int status, char const *phrase,
@@ -386,6 +418,8 @@
assert(m); assert(m->msg); assert(m->tport);
assert(100 <= status && status < 700);
+ s2_save_uas_dialog(d, m->sip);
+
ta_start(ta, tag, value);
reply = s2_msg(0); sip = sip_object(reply); home = msg_home(reply);
@@ -414,13 +448,7 @@
}
}
- if (d && !d->local) {
- d->local = sip_from_dup(d->home, sip->sip_to);
- d->remote = sip_to_dup(d->home, sip->sip_from);
- d->call_id = sip_call_id_dup(d->home, sip->sip_call_id);
- d->rseq = sip->sip_cseq->cs_seq;
- /* d->route = sip_route_dup(d->home, sip->sip_record_route); */
- d->target = sip_contact_dup(d->home, m->sip->sip_contact);
+ if (d && !d->contact) {
d->contact = sip_contact_dup(d->home, sip->sip_contact);
}
@@ -806,6 +834,9 @@
char const *description)
{
_s2case = number;
+
+ if (s2_start_stop)
+ printf("%s - starting %s %s\n", s2_tester, number, title);
}
/* ---------------------------------------------------------------------- */
@@ -875,10 +906,14 @@
}};
/** Basic setup for test cases */
-void s2_setup_base(char const *hostname)
+void s2_setup_base(char const *label, char const *hostname)
{
assert(s2 == NULL);
+ if (s2_start_stop > 1) {
+ printf("%s - setup %s test case\n", s2_tester, label ? label : "next");
+ }
+
su_init();
s2 = su_home_new(sizeof *s2);
@@ -897,6 +932,7 @@
s2->hostname = hostname;
s2->tid = (unsigned long)time(NULL) * 510633671UL;
+
}
SOFIAPUBVAR su_log_t nua_log[];
@@ -1489,22 +1525,43 @@
va_end(va0);
}
+static char const *s2_teardown_label = NULL;
+
+void
+s2_teardown_started(char const *label)
+{
+ if (!s2_teardown_label) {
+ s2_teardown_label = label;
+ if (s2_start_stop > 1) {
+ printf("%s - tearing down %s test case\n", s2_tester, label);
+ }
+ }
+}
+
void
s2_teardown(void)
{
s2 = NULL;
su_deinit();
+
+ if (s2_start_stop > 1) {
+ printf("%s - %s test case tore down\n", s2_tester,
+ s2_teardown_label ? s2_teardown_label : "previous");
+ }
+
+ s2_teardown_label = NULL;
}
/* ====================================================================== */
#include <sofia-sip/sresolv.h>
-nua_t *s2_nua_setup(tag_type_t tag, tag_value_t value, ...)
+nua_t *s2_nua_setup(char const *label,
+ tag_type_t tag, tag_value_t value, ...)
{
ta_list ta;
- s2_setup_base(NULL);
+ s2_setup_base(label, NULL);
s2_setup_dns();
s2_setup_logs(0);
@@ -1618,4 +1675,3 @@
s2->registration->nh = NULL;
}
}
-
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/test_s2.h
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/test_s2.h (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/test_s2.h Wed Feb 11 11:08:41 2009
@@ -102,6 +102,8 @@
msg_t *invite; /* latest invite sent */
};
+extern char const *s2_tester;
+extern int s2_start_stop;
extern struct tester *s2;
extern tp_stack_class_t const s2_stack[1];
@@ -144,8 +146,12 @@
struct message *s2_wait_for_request(sip_method_t method, char const *name);
int s2_check_request(sip_method_t method, char const *name);
+int s2_check_substate(struct event *e, enum nua_substate state);
+
#define SIP_METHOD_UNKNOWN sip_method_unknown, NULL
+void s2_save_uas_dialog(struct dialog *d, sip_t *sip);
+
struct message *s2_respond_to(struct message *m, struct dialog *d,
int status, char const *phrase,
tag_type_t tag, tag_value_t value, ...);
@@ -161,15 +167,16 @@
void s2_flush_all(void);
-void s2_setup_base(char const *hostname);
+void s2_setup_base(char const *label, char const *hostname);
void s2_setup_logs(int level);
void s2_setup_tport(char const * const *protocols,
tag_type_t tag, tag_value_t value, ...);
void s2_teardown(void);
-nua_t *s2_nua_setup(tag_type_t tag, tag_value_t value, ...);
-void s2_nua_teardown(void);
+nua_t *s2_nua_setup(char const *label, tag_type_t tag, tag_value_t value, ...);
+void s2_teardown_started(char const *label);
+void s2_nua_teardown(void);
void s2_register_setup(void);
void s2_register_teardown(void);
1
0
[commit] r11835 - in freeswitch/trunk/libs/sofia-sip: . libsofia-sip-ua/soa
by FreeSWITCH SVN 11 Feb '09
by FreeSWITCH SVN 11 Feb '09
11 Feb '09
Author: mikej
Date: Wed Feb 11 11:07:59 2009
New Revision: 11835
Log:
Fri Jan 16 13:27:39 CST 2009 Pekka Pessi <first.last(a)nokia.com>
* soa: fixed restoring state after failed offer
Modified:
freeswitch/trunk/libs/sofia-sip/.update
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/soa/soa.c
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c
Modified: freeswitch/trunk/libs/sofia-sip/.update
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/.update (original)
+++ freeswitch/trunk/libs/sofia-sip/.update Wed Feb 11 11:07:59 2009
@@ -1 +1 @@
-Wed Feb 11 11:06:56 CST 2009
+Wed Feb 11 11:07:52 CST 2009
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/soa/soa.c
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/soa/soa.c (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/soa/soa.c Wed Feb 11 11:07:59 2009
@@ -938,7 +938,7 @@
*
* <i>User SDP</i> is used as basis for SDP Offer/Answer negotiation. It can
* be very minimal template, consisting just m= line containing media name,
- * transport protocol port number and list of supported codecs.
+ * transport protocol, port number and list of supported codecs.
*
* The SDP used as an offer or answer (generated by soa_generate_answer() or
* soa_generate_offer()) is known as <i>local SDP</i> and it is available
@@ -1703,13 +1703,10 @@
(void)completed;
- if (!l_sdp)
- return -1;
-
- soa_set_activity(ss, l_sdp->sdp_media, soa_activity_session);
-
ss->ss_offer_sent = 0;
+ soa_set_activity(ss, l_sdp ? l_sdp->sdp_media : NULL, soa_activity_session);
+
return 0;
}
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c Wed Feb 11 11:07:59 2009
@@ -84,6 +84,11 @@
/** Mapping from session SDP m= lines to user SDP m= lines */
int *sss_s2u;
+ /** State kept from SDP before current offer */
+ struct {
+ int *u2s, *s2u;
+ } sss_previous;
+
/** Our latest offer or answer */
sdp_session_t *sss_latest;
}
@@ -886,6 +891,7 @@
return 0;
}
+static
int *u2s_alloc(su_home_t *home, int const *u2s)
{
if (u2s) {
@@ -1318,6 +1324,8 @@
}
soa_description_free(ss, ss->ss_previous);
+ su_free(ss->ss_home, sss->sss_previous.u2s), sss->sss_previous.u2s = NULL;
+ su_free(ss->ss_home, sss->sss_previous.s2u), sss->sss_previous.s2u = NULL;
if (u2s) {
u2s = u2s_alloc(ss->ss_home, u2s);
@@ -1358,10 +1366,18 @@
if (action == generate_offer) {
/* Keep a copy of previous session state */
+ int *previous_u2s = u2s_alloc(ss->ss_home, sss->sss_u2s);
+ int *previous_s2u = u2s_alloc(ss->ss_home, sss->sss_s2u);
+
+ if ((sss->sss_u2s && !previous_u2s) || (sss->sss_s2u && !previous_s2u))
+ goto internal_error;
+
*ss->ss_previous = *ss->ss_local;
memset(ss->ss_local, 0, (sizeof *ss->ss_local));
ss->ss_previous_user_version = ss->ss_local_user_version;
ss->ss_previous_remote_version = ss->ss_local_remote_version;
+ sss->sss_previous.u2s = previous_u2s;
+ sss->sss_previous.s2u = previous_s2u;
}
SU_DEBUG_7(("soa_static(%p, %s): %s\n", (void *)ss, by,
@@ -1374,6 +1390,8 @@
memset(ss->ss_previous, 0, (sizeof *ss->ss_previous));
ss->ss_previous_user_version = 0;
ss->ss_previous_remote_version = 0;
+ su_free(ss->ss_home, sss->sss_previous.u2s), sss->sss_previous.u2s = NULL;
+ su_free(ss->ss_home, sss->sss_previous.s2u), sss->sss_previous.s2u = NULL;
}
su_free(ss->ss_home, u2s), su_free(ss->ss_home, s2u);
@@ -1467,21 +1485,26 @@
static int soa_static_process_reject(soa_session_t *ss,
soa_callback_f *completed)
{
+ soa_static_session_t *sss = (soa_static_session_t *)ss;
struct soa_description d[1];
- if (ss->ss_previous_user_version) {
- *d = *ss->ss_local;
- *ss->ss_local = *ss->ss_previous;
- ss->ss_local_user_version = ss->ss_previous_user_version;
- ss->ss_local_remote_version = ss->ss_previous_remote_version;
-
- memset(ss->ss_previous, 0, (sizeof *ss->ss_previous));
- soa_description_free(ss, d);
- ss->ss_previous_user_version = 0;
- ss->ss_previous_remote_version = 0;
- }
+ soa_base_process_reject(ss, NULL);
+
+ *d = *ss->ss_local;
+ *ss->ss_local = *ss->ss_previous;
+ ss->ss_local_user_version = ss->ss_previous_user_version;
+ ss->ss_local_remote_version = ss->ss_previous_remote_version;
+
+ memset(ss->ss_previous, 0, (sizeof *ss->ss_previous));
+ soa_description_free(ss, d);
+ su_free(ss->ss_home, sss->sss_previous.u2s), sss->sss_previous.u2s = NULL;
+ su_free(ss->ss_home, sss->sss_previous.s2u), sss->sss_previous.s2u = NULL;
+ ss->ss_previous_user_version = 0;
+ ss->ss_previous_remote_version = 0;
- return soa_base_process_reject(ss, NULL);
+ su_free(ss->ss_home, sss->sss_latest), sss->sss_latest = NULL;
+
+ return 0;
}
static int soa_static_activate(soa_session_t *ss, char const *option)
@@ -1496,6 +1519,19 @@
static void soa_static_terminate(soa_session_t *ss, char const *option)
{
- soa_description_free(ss, ss->ss_user);
+ soa_static_session_t *sss = (soa_static_session_t *)ss;
+
+ soa_description_free(ss, ss->ss_local);
+ su_free(ss->ss_home, sss->sss_u2s), sss->sss_u2s = NULL;
+ su_free(ss->ss_home, sss->sss_s2u), sss->sss_s2u = NULL;
+
+ soa_description_free(ss, ss->ss_previous);
+ ss->ss_previous_user_version = 0;
+ ss->ss_previous_remote_version = 0;
+ su_free(ss->ss_home, sss->sss_previous.u2s), sss->sss_previous.u2s = NULL;
+ su_free(ss->ss_home, sss->sss_previous.s2u), sss->sss_previous.s2u = NULL;
+
+ su_free(ss->ss_home, sss->sss_latest), sss->sss_latest = NULL;
+
soa_base_terminate(ss, option);
}
1
0
[commit] r11834 - in freeswitch/trunk/libs/sofia-sip: . libsofia-sip-ua/nua
by FreeSWITCH SVN 11 Feb '09
by FreeSWITCH SVN 11 Feb '09
11 Feb '09
Author: mikej
Date: Wed Feb 11 11:07:09 2009
New Revision: 11834
Log:
Fri Jan 16 07:42:29 CST 2009 Pekka Pessi <first.last(a)nokia.com>
* nua: fixed problems with route set handling
RFC 3261 allows the route set changes while dialog is in early state.
Modified:
freeswitch/trunk/libs/sofia-sip/.update
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/check_session.c
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.c
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.h
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c
Modified: freeswitch/trunk/libs/sofia-sip/.update
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/.update (original)
+++ freeswitch/trunk/libs/sofia-sip/.update Wed Feb 11 11:07:09 2009
@@ -1 +1 @@
-Wed Feb 11 11:05:49 CST 2009
+Wed Feb 11 11:06:56 CST 2009
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/check_session.c
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/check_session.c (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/check_session.c Wed Feb 11 11:07:09 2009
@@ -41,6 +41,7 @@
#include <sofia-sip/sip_header.h>
#include <sofia-sip/soa.h>
#include <sofia-sip/su_tagarg.h>
+#include <sofia-sip/su_string.h>
#include <sofia-sip/su_tag_io.h>
#include <stdlib.h>
@@ -1007,8 +1008,10 @@
/* 2.3 - Session timers */
/* Wait for invite from NUA */
-static void invite_timer_round(nua_handle_t *nh,
- char const *session_expires)
+static struct message *
+invite_timer_round(nua_handle_t *nh,
+ char const *session_expires,
+ sip_record_route_t *rr)
{
struct message *invite, *ack;
@@ -1019,17 +1022,27 @@
invite, dialog, SIP_200_OK,
SIPTAG_SESSION_EXPIRES_STR(session_expires),
SIPTAG_REQUIRE_STR("timer"),
+ SIPTAG_RECORD_ROUTE(rr),
TAG_END());
s2_free_message(invite);
fail_unless(s2_check_event(nua_r_invite, 200));
fail_unless(s2_check_callstate(nua_callstate_ready));
ack = s2_wait_for_request(SIP_METHOD_ACK);
- s2_free_message(ack);
+ if (rr == NULL)
+ s2_free_message(ack);
+ return ack;
}
START_TEST(call_2_3_1)
{
nua_handle_t *nh;
+ sip_record_route_t rr[1];
+ struct message *ack;
+
+ sip_record_route_init(rr);
+ *rr->r_url = *s2->contact->m_url;
+ rr->r_url->url_user = "record";
+ rr->r_url->url_params = "lr";
s2_case("2.3.1", "Incoming call with call timers",
"NUA receives INVITE, "
@@ -1043,9 +1056,11 @@
TAG_END());
s2_fast_forward(300);
- invite_timer_round(nh, "300;refresher=uac");
+ ack = invite_timer_round(nh, "300;refresher=uac", rr);
+ fail_if(ack->sip->sip_route &&
+ su_strmatch(ack->sip->sip_route->r_url->url_user, "record"));
s2_fast_forward(300);
- invite_timer_round(nh, "300;refresher=uac");
+ invite_timer_round(nh, "300;refresher=uac", NULL);
bye_by_nua(nh, TAG_END());
@@ -1069,9 +1084,9 @@
TAG_END());
s2_fast_forward(300);
- invite_timer_round(nh, "300");
+ invite_timer_round(nh, "300", NULL);
s2_fast_forward(300);
- invite_timer_round(nh, "300");
+ invite_timer_round(nh, "300", NULL);
bye_by_nua(nh, TAG_END());
@@ -1098,8 +1113,9 @@
START_TEST(call_2_4_1)
{
nua_handle_t *nh;
- struct message *invite, *prack;
+ struct message *invite, *prack, *ack;
int with_sdp;
+ sip_record_route_t rr[1];
s2_case("2.4.1", "Call with 100rel",
"NUA sends INVITE, "
@@ -1107,6 +1123,11 @@
"receives 180, sends PRACK, receives 200 for it, "
"receives 200, send ACK.");
+ sip_record_route_init(rr);
+ *rr->r_url = *s2->contact->m_url;
+ rr->r_url->url_user = "record";
+ rr->r_url->url_params = "lr";
+
nh = nua_handle(nua, NULL, SIPTAG_TO(s2->local), TAG_END());
invite = invite_sent_by_nua(
@@ -1116,6 +1137,7 @@
prack = respond_with_100rel(invite, dialog, with_sdp = 1,
SIP_183_SESSION_PROGRESS,
+ SIPTAG_RECORD_ROUTE(rr),
TAG_END());
s2_respond_to(prack, dialog, SIP_200_OK, TAG_END());
s2_free_message(prack), prack = NULL;
@@ -1125,16 +1147,26 @@
prack = respond_with_100rel(invite, dialog, with_sdp = 0,
SIP_180_RINGING,
TAG_END());
+ fail_unless(prack->sip->sip_route != NULL);
+ fail_unless(su_strmatch(prack->sip->sip_route->r_url->url_user, "record"));
+
s2_respond_to(prack, dialog, SIP_200_OK, TAG_END());
s2_free_message(prack), prack = NULL;
fail_unless(s2_check_callstate(nua_callstate_proceeding));
fail_unless(s2_check_event(nua_r_prack, 200));
- s2_respond_to(invite, dialog, SIP_200_OK, TAG_END());
+ /* Change the record-route */
+ rr->r_url->url_user = "record2";
+ s2_respond_to(invite, dialog, SIP_200_OK,
+ SIPTAG_RECORD_ROUTE(rr),
+ TAG_END());
s2_free_message(invite);
fail_unless(s2_check_event(nua_r_invite, 200));
fail_unless(s2_check_callstate(nua_callstate_ready));
- fail_unless(s2_check_request(SIP_METHOD_ACK));
+ ack = s2_wait_for_request(SIP_METHOD_ACK);
+ fail_if(!ack);
+ fail_unless(su_strmatch(ack->sip->sip_route->r_url->url_user, "record2"));
+ s2_free_message(ack);
bye_to_nua(nh, TAG_END());
@@ -2314,7 +2346,7 @@
TAG_END());
s2_fast_forward(300);
- invite_timer_round(nh, "300");
+ invite_timer_round(nh, "300", NULL);
nua_bye(nh, TAG_END());
@@ -2358,7 +2390,7 @@
TAG_END());
s2_fast_forward(300);
- invite_timer_round(nh, "300");
+ invite_timer_round(nh, "300", NULL);
s2_fast_forward(300);
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.c
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.c (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.c Wed Feb 11 11:07:09 2009
@@ -104,13 +104,16 @@
* @param ds dialog state
* @param sip SIP message containing response used to update dialog
* @param rtag if true, set remote tag within the leg
+ * @param initial if true, @a sip is response to initial transaction
*/
void nua_dialog_uac_route(nua_owner_t *own,
nua_dialog_state_t *ds,
sip_t const *sip,
- int rtag)
+ int rtag,
+ int initial)
{
int established = nua_dialog_is_established(ds);
+ int status = sip->sip_status->st_status;
if (!established && sip->sip_to->a_tag)
ds->ds_remote_tag = su_strdup(own, sip->sip_to->a_tag);
@@ -118,7 +121,11 @@
if (ds->ds_leg == NULL)
return;
- nta_leg_client_route(ds->ds_leg, sip->sip_record_route, sip->sip_contact);
+ if (initial && status >= 200)
+ nta_leg_client_reroute(ds->ds_leg, sip->sip_record_route, sip->sip_contact, 1);
+ else
+ nta_leg_client_reroute(ds->ds_leg, sip->sip_record_route, sip->sip_contact, 0);
+
ds->ds_route = ds->ds_route || sip->sip_record_route || sip->sip_contact;
if (rtag && !established && sip->sip_to->a_tag)
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.h
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.h (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.h Wed Feb 11 11:07:09 2009
@@ -299,6 +299,7 @@
unsigned cr_dialog:1; /**< Request can initiate dialog */
/* Current state */
+ unsigned cr_initial:1; /**< Initial request of a dialog */
unsigned cr_acked:1; /**< Final response to the request has been ACKed */
unsigned cr_waiting:1; /**< Request is waiting */
unsigned cr_challenged:1; /**< Request was challenged */
@@ -411,7 +412,7 @@
};
void nua_dialog_uac_route(nua_owner_t *, nua_dialog_state_t *ds,
- sip_t const *sip, int rtag);
+ sip_t const *sip, int rtag, int initial);
void nua_dialog_uas_route(nua_owner_t *, nua_dialog_state_t *ds,
sip_t const *sip, int rtag);
void nua_dialog_store_peer_info(nua_owner_t *, nua_dialog_state_t *ds,
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c Wed Feb 11 11:07:09 2009
@@ -732,9 +732,12 @@
if (sr->sr_usage == du && sr->sr_method == sip_method_invite &&
nua_server_request_is_pending(sr))
return nua_client_return(cr, SIP_491_REQUEST_PENDING, msg);
+ cr->cr_initial = 0;
}
- else
+ else {
du = nua_dialog_usage_add(nh, nh->nh_ds, nua_session_usage, NULL);
+ cr->cr_initial = 1;
+ }
if (!du)
return -1;
@@ -884,7 +887,7 @@
if (!nua_dialog_is_established(nh->nh_ds)) {
nta_outgoing_t *tagged;
- nua_dialog_uac_route(nh, nh->nh_ds, sip, 1);
+ nua_dialog_uac_route(nh, nh->nh_ds, sip, 1, 1);
nua_dialog_store_peer_info(nh, nh->nh_ds, sip);
/* Tag the INVITE request */
@@ -1188,7 +1191,6 @@
}
nua_client_request_ref(cr);
-
error = nua_invite_client_ack(cr, tags);
if (error < 0) {
@@ -1238,6 +1240,8 @@
assert(cr->cr_orq);
assert(cr->cr_method == sip_method_invite);
+ cr->cr_initial = 0;
+
if (!ds->ds_leg) {
/* XXX - fix nua_dialog_usage_remove_at() instead! */
nua_client_request_clean(cr);
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c Wed Feb 11 11:07:09 2009
@@ -2876,7 +2876,7 @@
else {
if (sip) {
if (cr->cr_contactize)
- nua_dialog_uac_route(nh, nh->nh_ds, sip, 1);
+ nua_dialog_uac_route(nh, nh->nh_ds, sip, 1, cr->cr_initial);
nua_dialog_store_peer_info(nh, nh->nh_ds, sip);
}
1
0
[commit] r11833 - in freeswitch/trunk/libs/sofia-sip: . libsofia-sip-ua/nta libsofia-sip-ua/nta/sofia-sip
by FreeSWITCH SVN 11 Feb '09
by FreeSWITCH SVN 11 Feb '09
11 Feb '09
Author: mikej
Date: Wed Feb 11 11:06:00 2009
New Revision: 11833
Log:
Fri Jan 16 07:22:08 CST 2009 Pekka Pessi <first.last(a)nokia.com>
* nta: added nta_leg_client_reroute()
nta_leg_client_route() did not catch actually RFC 3261 section 12.1.2 feel
and spirit, not to speak about letter.
Modified:
freeswitch/trunk/libs/sofia-sip/.update
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nta/nta.c
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nta/sofia-sip/nta.h
Modified: freeswitch/trunk/libs/sofia-sip/.update
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/.update (original)
+++ freeswitch/trunk/libs/sofia-sip/.update Wed Feb 11 11:06:00 2009
@@ -1 +1 @@
-Wed Feb 11 11:05:09 CST 2009
+Wed Feb 11 11:05:49 CST 2009
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nta/nta.c
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nta/nta.c (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nta/nta.c Wed Feb 11 11:06:00 2009
@@ -363,6 +363,7 @@
#else
unsigned leg_loose_route : 1; /**< Topmost route in set is LR */
#endif
+ unsigned leg_route_set : 1; /**< Route set has been saved */
unsigned leg_local_is_to : 1; /**< Backwards-compatibility. */
unsigned leg_tagged : 1; /**< Tagged after creation.
*
@@ -3970,7 +3971,8 @@
static int leg_route(nta_leg_t *leg,
sip_record_route_t const *route,
sip_record_route_t const *reverse,
- sip_contact_t const *contact);
+ sip_contact_t const *contact,
+ int reroute);
static int leg_callback_default(nta_leg_magic_t*, nta_leg_t*,
nta_incoming_t*, sip_t const *);
#define HTABLE_HASH_LEG(leg) ((leg)->leg_hash)
@@ -4469,24 +4471,55 @@
/** Save target and route set at UAC side.
*
- * @sa nta_leg_server_route(), @RFC3261 section 12.1.2
+ * @sa nta_leg_client_reroute(), nta_leg_server_route(), @RFC3261 section 12.1.2
+ *
+ * @bug Allows modifying the route set after initial transaction, if initial
+ * transaction had no @RecordRoute headers.
+ *
+ * @deprecated Use nta_leg_client_reroute() instead.
*/
int nta_leg_client_route(nta_leg_t *leg,
sip_record_route_t const *route,
sip_contact_t const *contact)
{
- return leg_route(leg, NULL, route, contact);
+ return leg_route(leg, NULL, route, contact, 0);
+}
+
+/** Save target and route set at UAC side.
+ *
+ * If @a initial is true, the route set is modified even if it has been set
+ * earlier.
+ *
+ * @param leg pointer to dialog leg
+ * @param route @RecordRoute headers from response
+ * @param contact @Contact header from response
+ * @param initial true if response to initial transaction
+ *
+ * @sa nta_leg_client_route(), nta_leg_server_route(), @RFC3261 section 12.1.2
+ *
+ * @NEW_1_12_11
+ */
+int nta_leg_client_reroute(nta_leg_t *leg,
+ sip_record_route_t const *route,
+ sip_contact_t const *contact,
+ int initial)
+{
+ return leg_route(leg, NULL, route, contact, initial ? 2 : 1);
}
/** Save target and route set at UAS side.
*
- * @sa nta_leg_client_route(), @RFC3261 section 12.1.1
+ * @param leg pointer to dialog leg
+ * @param route @RecordRoute headers from request
+ * @param contact @Contact header from request
+ *
+ * @sa nta_leg_client_reroute(), @RFC3261 section 12.1.1
*/
int nta_leg_server_route(nta_leg_t *leg,
sip_record_route_t const *route,
sip_contact_t const *contact)
{
- return leg_route(leg, route, NULL, contact);
+ return leg_route(leg, route, NULL, contact, 1);
}
/** Return route components. */
@@ -4940,15 +4973,21 @@
*
* Sets the leg route and contact using the @RecordRoute and @Contact
* headers.
+ *
+ * @param reroute - allow rerouting
+ * - if 1, follow @RFC3261 semantics
+ * - if 2, response to initial transaction)
*/
static
int leg_route(nta_leg_t *leg,
sip_record_route_t const *route,
sip_record_route_t const *reverse,
- sip_contact_t const *contact)
+ sip_contact_t const *contact,
+ int reroute)
{
su_home_t *home = leg->leg_home;
- sip_route_t *r, r0[1];
+ sip_route_t *r, r0[1], *old;
+ int route_is_set;
if (!leg)
return -1;
@@ -4958,7 +4997,9 @@
sip_route_init(r0);
- if (leg->leg_route) {
+ route_is_set = reroute ? leg->leg_route_set : leg->leg_route != NULL;
+
+ if (route_is_set && reroute <= 1) {
r = leg->leg_route;
}
else if (route) {
@@ -5023,8 +5064,14 @@
}
#endif
+ old = leg->leg_route;
leg->leg_route = r;
+ if (old && old != r)
+ msg_header_free(leg->leg_home, (msg_header_t *)old);
+
+ leg->leg_route_set = 1;
+
return 0;
}
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nta/sofia-sip/nta.h
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nta/sofia-sip/nta.h (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nta/sofia-sip/nta.h Wed Feb 11 11:06:00 2009
@@ -216,12 +216,15 @@
/** Get remote request sequence number. @NEW_1_12_9 */
SOFIAPUBFUN uint32_t nta_leg_get_rseq(nta_leg_t const *leg);
-/** Set UAC route. */
SOFIAPUBFUN int nta_leg_client_route(nta_leg_t *leg,
sip_record_route_t const *route,
sip_contact_t const *contact);
-/** Set UAS route */
+SOFIAPUBFUN int nta_leg_client_reroute(nta_leg_t *leg,
+ sip_record_route_t const *route,
+ sip_contact_t const *contact,
+ int initial);
+
SOFIAPUBFUN int nta_leg_server_route(nta_leg_t *leg,
sip_record_route_t const *route,
sip_contact_t const *contact);
1
0
11 Feb '09
Author: mikej
Date: Wed Feb 11 11:05:32 2009
New Revision: 11832
Log:
Thu Jan 15 12:06:29 CST 2009 Pekka Pessi <first.last(a)nokia.com>
* check_session.c: make sure To header in ACK to [3456]XX is copied from response
Modified:
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/check_session.c
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/check_session.c
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/check_session.c (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/check_session.c Wed Feb 11 11:05:32 2009
@@ -1663,7 +1663,7 @@
START_TEST(call_3_1_1)
{
nua_handle_t *nh;
- struct message *invite;
+ struct message *invite, *ack;
s2_case("3.1.1", "Call failure", "Call fails with 403 response");
nh = nua_handle(nua, NULL, SIPTAG_TO(s2->local),
@@ -1676,10 +1676,15 @@
invite = s2_wait_for_request(SIP_METHOD_INVITE);
fail_if(!invite);
- s2_respond_to(invite, NULL, SIP_403_FORBIDDEN, TAG_END());
+ s2_respond_to(invite, NULL, SIP_403_FORBIDDEN,
+ SIPTAG_TO_STR("UAS Changed <sip:To@Header.field.invalid>"),
+ TAG_END());
s2_free_message(invite);
- fail_unless(s2_check_request(SIP_METHOD_ACK));
+ ack = s2_wait_for_request(SIP_METHOD_ACK);
+ fail_if(!ack);
+ fail_if(strcmp(ack->sip->sip_to->a_display, "UAS Changed"));
+ s2_free_message(ack);
fail_unless(s2_check_event(nua_r_invite, 403));
fail_unless(s2_check_callstate(nua_callstate_terminated));
1
0
[commit] r11831 - in freeswitch/trunk/libs/sofia-sip: . libsofia-sip-ua/nta
by FreeSWITCH SVN 11 Feb '09
by FreeSWITCH SVN 11 Feb '09
11 Feb '09
Author: mikej
Date: Wed Feb 11 11:05:16 2009
New Revision: 11831
Log:
Thu Jan 15 12:06:00 CST 2009 Pekka Pessi <first.last(a)nokia.com>
* nta.c: when sending ACK to [3456]XX, copy the To header as-is from the response
Problem reported by Paulo Pizarro.
Modified:
freeswitch/trunk/libs/sofia-sip/.update
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nta/nta.c
Modified: freeswitch/trunk/libs/sofia-sip/.update
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/.update (original)
+++ freeswitch/trunk/libs/sofia-sip/.update Wed Feb 11 11:05:16 2009
@@ -1 +1 @@
-Wed Feb 11 11:03:50 CST 2009
+Wed Feb 11 11:05:09 CST 2009
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nta/nta.c
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nta/nta.c (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nta/nta.c Wed Feb 11 11:05:16 2009
@@ -7001,7 +7001,7 @@
static void outgoing_ack(nta_outgoing_t *orq, sip_t *sip);
static msg_t *outgoing_ackmsg(nta_outgoing_t *, sip_method_t, char const *,
- tagi_t const *tags);
+ tag_type_t tag, tag_value_t value, ...);
static void outgoing_retransmit(nta_outgoing_t *orq);
static void outgoing_trying(nta_outgoing_t *orq);
static void outgoing_timeout(nta_outgoing_t *orq, uint32_t now);
@@ -7307,7 +7307,7 @@
TAG_END());
if (!cancel_408)
- msg = outgoing_ackmsg(orq, SIP_METHOD_CANCEL, ta_args(ta));
+ msg = outgoing_ackmsg(orq, SIP_METHOD_CANCEL, ta_tags(ta));
else
msg = NULL;
@@ -9193,7 +9193,6 @@
{
nta_outgoing_t *ack;
msg_t *ackmsg;
- sip_t *acksip;
assert(orq);
@@ -9205,13 +9204,9 @@
assert(sip->sip_status->st_status >= 300);
assert(orq->orq_tport);
- ackmsg = outgoing_ackmsg(orq, SIP_METHOD_ACK, NULL);
- acksip = sip_object(ackmsg);
-
- if (acksip) {
- if (sip->sip_to->a_tag && !acksip->sip_to->a_tag)
- sip_to_tag(msg_home(ackmsg), acksip->sip_to, sip->sip_to->a_tag);
+ ackmsg = outgoing_ackmsg(orq, SIP_METHOD_ACK, SIPTAG_TO(sip->sip_to), TAG_END());
+ if (ackmsg) {
if ((ack = outgoing_create(orq->orq_agent, NULL, NULL,
NULL, orq->orq_tpn, ackmsg,
NTATAG_BRANCH_KEY(sip->sip_via->v_branch),
@@ -9227,7 +9222,7 @@
/** Generate messages for hop-by-hop ACK or CANCEL.
*/
msg_t *outgoing_ackmsg(nta_outgoing_t *orq, sip_method_t m, char const *mname,
- tagi_t const *tags)
+ tag_type_t tag, tag_value_t value, ...)
{
msg_t *msg = nta_msg_create(orq->orq_agent, 0);
su_home_t *home = msg_home(msg);
@@ -9238,8 +9233,12 @@
if (!sip)
return NULL;
- if (tags) {
- sip_add_tl(msg, sip, TAG_NEXT(tags));
+ if (tag) {
+ ta_list ta;
+
+ ta_start(ta, tag, value);
+
+ sip_add_tl(msg, sip, ta_tags(ta));
/* Bug sf.net # 173323:
* Ensure that request-URI, topmost Via, From, To, Call-ID, CSeq,
* Max-Forward, Route, Accept-Contact, Reject-Contact and
@@ -9247,7 +9246,7 @@
*/
if (sip->sip_from)
sip_header_remove(msg, sip, (void *)sip->sip_from);
- if (sip->sip_to)
+ if (sip->sip_to && m != sip_method_ack)
sip_header_remove(msg, sip, (void *)sip->sip_to);
if (sip->sip_call_id)
sip_header_remove(msg, sip, (void *)sip->sip_call_id);
@@ -9263,12 +9262,15 @@
sip_header_remove(msg, sip, (void *)sip->sip_via);
if (sip->sip_max_forwards)
sip_header_remove(msg, sip, (void *)sip->sip_max_forwards);
+
+ ta_end(ta);
}
sip->sip_request =
sip_request_create(home, m, mname, (url_string_t *)orq->orq_url, NULL);
- sip_add_dup(msg, sip, (sip_header_t *)old->sip_to);
+ if (sip->sip_to == NULL)
+ sip_add_dup(msg, sip, (sip_header_t *)old->sip_to);
sip_add_dup(msg, sip, (sip_header_t *)old->sip_from);
sip_add_dup(msg, sip, (sip_header_t *)old->sip_call_id);
sip_add_dup(msg, sip, (sip_header_t *)old->sip_route);
1
0
[commit] r11830 - in freeswitch/trunk/libs/sofia-sip: . libsofia-sip-ua/tport libsofia-sip-ua/tport/sofia-sip
by FreeSWITCH SVN 11 Feb '09
by FreeSWITCH SVN 11 Feb '09
11 Feb '09
Author: mikej
Date: Wed Feb 11 11:03:59 2009
New Revision: 11830
Log:
Thu Jan 15 09:50:45 CST 2009 Jarod Neuner <janeuner(a)networkharbor.com>
* TLS Subject Checking in tport
sofia-sip/tport.h:
* tport_delivered_from_subjects() returns type (su_strlst_t const *)
* Export tport_subject_search()
sofia-sip/tport_tag.h + tport_tag.c:
* Remove TPTAG_TLS_VERIFY_PEER()
- Depreciated. Use TPTAG_TLS_VERIFY_POLICY instead.
- Binary Compatibility is preserved.
* Add TPTAG_TLS_VERIFY_POLICY()
- tport can verify incoming and/or outgoing connections, using:
1) Certificate Signatures only - or -
2) Certificate Signatures and Certificate Subjects
* Add TPTAG_TLS_VERIFY_DEPTH()
- Restrict certificate chain verification to a set length.
* Add TPTAG_TLS_VERIFY_DATE()
- Disable notBefore/notAfter checking (application: embedded devices)
* Add TPTAG_TLS_VERIFY_SUBJECTS()
- Incoming connections must present client certificates with subjects
that match an item in this list.
- Intended Use: Proxy Authentication
* Replaced TPTAG_TRUSTED() with TPTAG_X509_SUBJECT()
- Commented out for future use.
- Intended Use: SIP User Identities in Server Certificates.
* Add appropriate doxygen documentation.
tport.c
* Add tport_subject_search()
- Subject can be a hostname, IP Address, or a URI.
- Valid subject examples include:
example.com
alice(a)example.com
sip:alice@example.com
sips:alice@example.com
* tport_by_addrinfo() matches tpn_canon against the subject list
of reusable TLS connections.
tport_tls.h:
* Add tls_init_secondary()
* Remove tls_init_slave() & tls_init_client()
tport_tls.c:
* tls_verify_cb() supports TPTAG_TLS_VERIFY_DATE()
* tls_post_connection_check() verifies certificate subjects.
* tls_init_secondary()
- Replaces tls_init_slave(), tls_init_client(), and tls_clone().
tport_type_tls.c:
* Removed erroneous reference to tport_tls_deliver()
* Fix a memory leak caused by duplicate calls to tls_clone().
* Populate the (tport_t *)->tp_subjects field with peer certificate data for
new secondary connections.
Modified:
freeswitch/trunk/libs/sofia-sip/.update
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/sofia-sip/tport.h
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/sofia-sip/tport_tag.h
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/tport.c
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/tport_internal.h
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/tport_tag.c
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.c
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.h
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_tls.c
Modified: freeswitch/trunk/libs/sofia-sip/.update
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/.update (original)
+++ freeswitch/trunk/libs/sofia-sip/.update Wed Feb 11 11:03:59 2009
@@ -1 +1 @@
-Wed Feb 11 11:03:24 CST 2009
+Wed Feb 11 11:03:50 CST 2009
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/sofia-sip/tport.h
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/sofia-sip/tport.h (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/sofia-sip/tport.h Wed Feb 11 11:03:59 2009
@@ -339,7 +339,11 @@
tp_name_t name[1]);
/** Return TLS Subjects provided by the source transport */
-TPORT_DLL su_strlst_t *tport_delivered_from_subjects(tport_t *tp, msg_t const *msg);
+TPORT_DLL su_strlst_t const *tport_delivered_from_subjects(tport_t *tp,
+ msg_t const *msg);
+
+/** Check if the given subject string is found in su_strlst_t */
+TPORT_DLL int tport_subject_search(char const *, su_strlst_t const *);
/** Check if transport named is already resolved */
TPORT_DLL int tport_name_is_resolved(tp_name_t const *);
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/sofia-sip/tport_tag.h
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/sofia-sip/tport_tag.h (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/sofia-sip/tport_tag.h Wed Feb 11 11:03:59 2009
@@ -186,18 +186,59 @@
TPORT_DLL extern tag_typedef_t tptag_tls_version_ref;
#define TPTAG_TLS_VERSION_REF(x) tptag_tls_version_ref, tag_uint_vr(&(x))
+enum tport_tls_verify_policy {
+ TPTLS_VERIFY_NONE = 0x0,
+ TPTLS_VERIFY_INCOMING = 0x1,
+ TPTLS_VERIFY_IN = 0x1,
+ TPTLS_VERIFY_OUTGOING = 0x2,
+ TPTLS_VERIFY_OUT = 0x2,
+ TPTLS_VERIFY_ALL = 0x3,
+ TPTLS_VERIFY_SUBJECTS_IN = 0x5, /* 0x4 | TPTLS_VERIFY_INCOMING */
+ TPTLS_VERIFY_SUBJECTS_OUT = 0xA, /* 0x8 | TPTLS_VERIFY_OUTGOING */
+ TPTLS_VERIFY_SUBJECTS_ALL = 0xF,
+};
+
+TPORT_DLL extern tag_typedef_t tptag_tls_verify_policy;
+#define TPTAG_TLS_VERIFY_POLICY(x) tptag_tls_verify_policy, tag_uint_v((x))
+
+TPORT_DLL extern tag_typedef_t tptag_tls_verify_policy_ref;
+#define TPTAG_TLS_VERIFY_POLICY_REF(x) tptag_tls_verify_policy_ref, tag_uint_vr(&(x))
+
+TPORT_DLL extern tag_typedef_t tptag_tls_verify_depth;
+#define TPTAG_TLS_VERIFY_DEPTH(x) tptag_tls_verify_depth, tag_uint_v((x))
+
+TPORT_DLL extern tag_typedef_t tptag_tls_verify_depth_ref;
+#define TPTAG_TLS_VERIFY_DEPTH_REF(x) \
+ tptag_tls_verify_depth_ref, tag_uint_vr(&(x))
+
+TPORT_DLL extern tag_typedef_t tptag_tls_verify_date;
+#define TPTAG_TLS_VERIFY_DATE(x) tptag_tls_verify_date, tag_uint_v((x))
+
+TPORT_DLL extern tag_typedef_t tptag_tls_verify_date_ref;
+#define TPTAG_TLS_VERIFY_DATE_REF(x) \
+ tptag_tls_verify_date_ref, tag_uint_vr(&(x))
+
+TPORT_DLL extern tag_typedef_t tptag_tls_verify_subjects;
+#define TPTAG_TLS_VERIFY_SUBJECTS(x) tptag_tls_verify_subjects, tag_cptr_v((x))
+
+TPORT_DLL extern tag_typedef_t tptag_tls_verify_subjects_ref;
+#define TPTAG_TLS_VERIFY_SUBJECTS_REF(x) \
+ tptag_tls_verify_subjects_ref, tag_cptr_vr(&(x), (x))
+
+/* TPTAG_TLS_VERIFY_PEER is depreciated - Use TPTAG_TLS_VERIFY_POLICY */
TPORT_DLL extern tag_typedef_t tptag_tls_verify_peer;
-#define TPTAG_TLS_VERIFY_PEER(x) tptag_tls_verify_peer, tag_uint_v((x))
+#define TPTAG_TLS_VERIFY_PEER(x) TPTAG_TLS_VERIFY_POLICY( (x) ? \
+ TPTLS_VERIFY_ALL : TPTLS_VERIFY_NONE)
TPORT_DLL extern tag_typedef_t tptag_tls_verify_peer_ref;
#define TPTAG_TLS_VERIFY_PEER_REF(x) tptag_tls_verify_peer_ref, tag_uint_vr(&(x))
#if 0
-TPORT_DLL extern tag_typedef_t tptag_trusted;
-#define TPTAG_TRUSTED(x) tptag_trusted, tag_bool_v((x))
+TPORT_DLL extern tag_typedef_t tport_x509_subject;
+#define TPTAG_X509_SUBJECT(x) tptag_x509_subject, tag_str_v((x))
-TPORT_DLL extern tag_typedef_t tptag_trusted_ref;
-#define TPTAG_TRUSTED_REF(x) tptag_trusted_ref, tag_bool_vr(&(x))
+TPORT_DLL extern tag_typedef_t tptag_x509_subject_ref;
+#define TPTAG_X509_SUBJECT_REF(x) tptag_x509_subject_ref, tag_str_vr(&(x))
#endif
TPORT_DLL extern tag_typedef_t tptag_debug_drop;
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/tport.c
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/tport.c (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/tport.c Wed Feb 11 11:03:59 2009
@@ -273,7 +273,7 @@
/** Return true if transport certificate verified successfully */
int tport_is_verified(tport_t const *self)
{
- return tport_has_tls(self) && self->tp_verified;
+ return tport_has_tls(self) && self->tp_is_connected && self->tp_verified;
}
/** Return true if transport is being updated. */
@@ -1465,8 +1465,8 @@
*
* @TAGS
* TPTAG_SERVER(), TPTAG_PUBLIC(), TPTAG_IDENT(), TPTAG_HTTP_CONNECT(),
- * TPTAG_CERTIFICATE(), TPTAG_TLS_VERSION(), TPTAG_TLS_VERIFY_PEER, and tags used with
- * tport_set_params(), especially TPTAG_QUEUESIZE().
+ * TPTAG_CERTIFICATE(), TPTAG_TLS_VERSION(), TPTAG_TLS_VERIFY_POLICY, and
+ * tags used with tport_set_params(), especially TPTAG_QUEUESIZE().
*/
int tport_tbind(tport_t *self,
tp_name_t const *tpn,
@@ -3045,7 +3045,7 @@
}
/** Return TLS Subjects provided by the source transport */
-su_strlst_t *tport_delivered_from_subjects(tport_t *tp, msg_t const *msg)
+su_strlst_t const *tport_delivered_from_subjects(tport_t *tp, msg_t const *msg)
{
if (tp && msg && msg == tp->tp_master->mr_delivery->d_msg) {
tport_t *tp_sec = tp->tp_master->mr_delivery->d_tport;
@@ -3069,6 +3069,57 @@
return 0;
}
+/** Search for subject in list of TLS Certificate subjects */
+int
+tport_subject_search(char const *subject, su_strlst_t const *lst)
+{
+ int idx, ilen;
+ const char *subjuri;
+
+ if (!subject || su_strmatch(tpn_any, subject))
+ return 1;
+
+ if (!lst)
+ return 0;
+
+ /* Check if subject is a URI */
+ if (su_casenmatch(subject,"sip:",4) || su_casenmatch(subject,"sips:",5))
+ subjuri = subject + su_strncspn(subject,5,":") + 1;
+ else
+ subjuri = NULL;
+
+ ilen = su_strlst_len(lst);
+
+ for (idx = 0; idx < ilen; idx++) {
+ const char *lsturi, *lststr;
+
+ lststr = su_strlst_item(lst, idx);
+
+ /* check if lststr is a URI (sips URI is an unacceptable cert subject) */
+ if (su_casenmatch(lststr,"sip:",4))
+ lsturi = lststr + su_strncspn(lststr,4,":") + 1;
+ else
+ lsturi = NULL;
+
+
+ /* Match two SIP Server Identities */
+ if (host_cmp(subjuri ? subjuri : subject, lsturi ? lsturi : lststr) == 0)
+ return 1;
+#if 0
+ /* XXX - IETF drafts forbid wildcard certs */
+ if (!subjuri && !lsturi && su_strnmatch("*.", lststr, 2)) {
+ size_t urioffset = su_strncspn(subject, 64, ".");
+ if (urioffset) {
+ if (su_casematch(subject + urioffset, lststr+1))
+ return 1;
+ }
+ }
+#endif
+ }
+
+ return 0;
+}
+
/** Allocate message for N bytes,
* return message buffer as a iovec
*/
@@ -3152,7 +3203,7 @@
*
* @TAGS
* TPTAG_MTU(), TPTAG_REUSE(), TPTAG_CLOSE_AFTER(), TPTAG_SDWN_AFTER(),
- * TPTAG_FRESH(), TPTAG_COMPARTMENT().
+ * TPTAG_FRESH(), TPTAG_COMPARTMENT(), TPTAG_X509_SUBJECT()
*/
tport_t *tport_tsend(tport_t *self,
msg_t *msg,
@@ -4581,6 +4632,13 @@
if (tport_is_shutdown(sub))
continue;
+ if (tport_has_tls(sub) && !su_casematch(tpn->tpn_canon, sub->tp_name->tpn_canon)) {
+ if (!tport_is_verified(sub))
+ continue;
+ if (!tport_subject_search(tpn->tpn_canon, sub->tp_subjects))
+ continue;
+ }
+
if (comp != sub->tp_name->tpn_comp)
continue;
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/tport_internal.h
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/tport_internal.h (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/tport_internal.h Wed Feb 11 11:03:59 2009
@@ -181,8 +181,10 @@
su_strlst_t *tp_subjects; /**< Transport Subjects.
*
- * Subject Name(s) provided by the
- * peer in a TLS connection (if secondary).
+ * Subject Name(s) provided by the peer
+ * in a TLS connection (if secondary).
+ * or matched against incoming
+ * connections (if primary).
*/
#define tp_protoname tp_name->tpn_proto
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/tport_tag.c
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/tport_tag.c (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/tport_tag.c Wed Feb 11 11:03:59 2009
@@ -281,20 +281,137 @@
tag_typedef_t tptag_tls_version = UINTTAG_TYPEDEF(tls_version);
/**@def TPTAG_TLS_VERIFY_PEER(x)
+ * @par Depreciated:
+ * Alias for TPTAG_TLS_VERIFY_POLICY(TPTLS_VERIFY_IN|TPTLS_VERIFY_OUT)
+ *
+ * @NEW_1_12_10.
+ */
+tag_typedef_t tptag_tls_verify_peer = UINTTAG_TYPEDEF(tls_verify_peer);
+
+/**@def TPTAG_TLS_VERIFY_POLICY(x)
*
* The verification of certificates can be controlled:
- * 0: no verify certificates;
- * 1: on server mode, the certificate returned by client is checked
- * if fail the TLS/SSL handshake is immediately terminated;
- * 1: on client mode, the server certificate is verified
- * if fail the TLS/SSL handshake is immediately terminated;
+ * @par Values:
+ * - #TPTLS_VERIFY_NONE:
+ * Do not verify Peer Certificates.
+ * - #TPTLS_VERIFY_IN:
+ * Drop incoming connections which fail signature verification
+ * against trusted certificate authorities. Peers must provide a
+ * certificate during the initial TLS Handshake.
+ * - #TPTLS_VERIFY_OUT:
+ * Drop outgoing connections which fail signature verification
+ * against trusted certificate authorities.
+ * - #TPTLS_VERIFY_ALL:
+ * Alias for (TPTLS_VERIFY_IN|TPTLS_VERIFY_OUT)
+ * - #TPTLS_VERIFY_SUBJECTS_IN:
+ * Match the certificate subject on incoming connections against
+ * a provided list. If no match is found, the connection is
+ * rejected. If no list is provided, subject checking is bypassed.
+ * Note: Implies #TPTLS_VERIFY_IN.
+ * - #TPTLS_VERIFY_SUBJECTS_OUT:
+ * Match the certificate subject on outgoing connections against
+ * a provided list. If no match is found, the connection is
+ * rejected.
+ * Note: Implies #TPTLS_VERIFY_OUT.
+ * - #TPTLS_VERIFY_SUBJECTS_ALL:
+ * Alias for (TPTLS_VERIFY_SUBJECTS_IN|TPTLS_VERIFY_SUBJECTS_OUT)
*
- * Use with tport_tbind(), nua_create(), nta_agent_create(),
- * nta_agent_add_tport(), nth_engine_create(), or initial nth_site_create().
+ * @par Used with
+ * tport_tbind(), nua_create(), nta_agent_create(), nta_agent_add_tport(),
+ * nth_engine_create(), initial nth_site_create(),
+ * TPTAG_TLS_VERIFY_SUBJECTS(), TPTAG_TLS_VERIFY_DEPTH().
*
- * @NEW_1_12_10.
+ * @NEW_1_12_11.
*/
-tag_typedef_t tptag_tls_verify_peer = UINTTAG_TYPEDEF(tls_verify_peer);
+tag_typedef_t tptag_tls_verify_policy = UINTTAG_TYPEDEF(tls_verify_policy);
+
+/**@def TPTAG_TLS_VERIFY_DEPTH(x)
+ *
+ * Define the maximum length of a valid certificate chain.
+ *
+ * @par Default
+ * 2
+ *
+ * @par Used with
+ * tport_tbind(), nua_create(), nta_agent_create(), nta_agent_add_tport(),
+ * nth_engine_create(), or initial nth_site_create().
+ *
+ * @par Parameter Type:
+ * unsigned int
+ *
+ * @NEW_1_12_11.
+ */
+tag_typedef_t tptag_tls_verify_depth = UINTTAG_TYPEDEF(tls_verify_depth);
+
+/**@def TPTAG_TLS_VERIFY_DATE(x)
+ *
+ * Enable/Disable verification of notBefore and notAfter parameters of
+ * X.509 Certificates.
+ *
+ * @par Default
+ * Enabled
+ *
+ * @par Values
+ * - 0 - Disable date verification.
+ * - Non-Zero - Enable date verification.
+ *
+ * @par Used with
+ * tport_tbind(), nua_create(), nta_agent_create(), nta_agent_add_tport(),
+ * nth_engine_create(), or initial nth_site_create().
+ *
+ * @par Parameter Type:
+ * unsigned int
+ *
+ * @par Note
+ * This tag should be only used on devices which lack accurate timekeeping.
+ *
+ * @NEW_1_12_11.
+ */
+tag_typedef_t tptag_tls_verify_date = UINTTAG_TYPEDEF(tls_verify_date);
+
+/**@def TPTAG_TLS_VERIFY_SUBJECTS(x)
+ *
+ * Incoming TLS connections must provide a trusted X.509 certificate.
+ * The character strings provided with this tag are matched against
+ * the subjects from the trusted certificate. If a match is not found,
+ * the connection is automatically rejected.
+ *
+ * @par Used with
+ * tport_tbind(), nua_create(), nta_agent_create(), nta_agent_add_tport(),
+ * nth_engine_create(), initial nth_site_create(),
+ * TPTLS_VERIFY_SUBJECTS_IN
+ *
+ * @par Parameter Type:
+ * void const * (actually su_strlst_t const *)
+ *
+ * @par Values
+ * - SIP Identity - sip:example.com or sip:username@example.com
+ * - DNS - sip.example.com
+ * - IP Address - Both IPv4 and IPv6 Supported
+ *
+ * @NEW_1_12_11.
+ */
+tag_typedef_t tptag_tls_verify_subjects = PTRTAG_TYPEDEF(tls_verify_subjects);
+
+#if 0
+/**@def TPTAG_X509_SUBJECT(x)
+ *
+ * Requires that a message be sent over a TLS transport with trusted X.509
+ * certificate. The character string provided must match against a subject
+ * from the trusted certificate.
+ *
+ * @par Used with
+ * tport_tsend(), TPTLS_VERIFY_SUBJECTS_OUT
+ *
+ * @par Parameter Type:
+ * char const *
+ *
+ * @par Values
+ * - Refer to TPTAG_TLS_VERIFY_SUBJECTS()
+ *
+ * @note Not Implemented.
+ */
+#endif
/**@def TPTAG_QUEUESIZE(x)
*
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.c
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.c (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.c Wed Feb 11 11:03:59 2009
@@ -56,7 +56,6 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
#if HAVE_SIGPIPE
#include <signal.h>
@@ -65,6 +64,7 @@
#include "tport_tls.h"
char const tls_version[] = OPENSSL_VERSION_TEXT;
+int tls_ex_data_idx = -1; /* see SSL_get_ex_new_index(3ssl) */
enum { tls_master = 0, tls_slave = 1};
@@ -75,9 +75,12 @@
BIO *bio_con;
unsigned int type:1,
accept:1,
- verify_outgoing:1,
verify_incoming:1,
- verified:1;
+ verify_outgoing:1,
+ verify_subj_in:1,
+ verify_subj_out:1,
+ verify_date:1,
+ x509_verified:1;
/* Receiving */
int read_events;
@@ -90,7 +93,7 @@
size_t write_buffer_len;
/* Host names */
- su_strlst_t *subject;
+ su_strlst_t *subjects;
};
enum { tls_buffer_size = 16384 };
@@ -162,13 +165,44 @@
X509 *cert = X509_STORE_CTX_get_current_cert(store);
int depth = X509_STORE_CTX_get_error_depth(store);
int err = X509_STORE_CTX_get_error(store);
+ int sslidx = SSL_get_ex_data_X509_STORE_CTX_idx();
+ SSL *ssl = X509_STORE_CTX_get_ex_data(store, sslidx);
+ tls_t *tls = SSL_get_ex_data(ssl, tls_ex_data_idx);
+
+ assert(tls);
+
+#define TLS_VERIFY_CB_CLEAR_ERROR(OK,ERR,STORE) \
+ do {\
+ OK = 1;\
+ ERR = X509_V_OK;\
+ X509_STORE_CTX_set_error(STORE,ERR);\
+ } while (0)
+
+ if (tls->accept && !tls->verify_incoming)
+ TLS_VERIFY_CB_CLEAR_ERROR(ok, err, store);
+ else if (!tls->accept && !tls->verify_outgoing)
+ TLS_VERIFY_CB_CLEAR_ERROR(ok, err, store);
+ else switch (err) {
+ case X509_V_ERR_CERT_NOT_YET_VALID:
+ case X509_V_ERR_CERT_HAS_EXPIRED:
+ case X509_V_ERR_CRL_NOT_YET_VALID:
+ case X509_V_ERR_CRL_HAS_EXPIRED:
+ if (!tls->verify_date)
+ TLS_VERIFY_CB_CLEAR_ERROR(ok, err, store);
+
+ default:
+ break;
+ }
+
+ if (!ok) {
+ SU_DEBUG_3(("-Error with certificate at depth: %i\n", depth));
+ X509_NAME_oneline(X509_get_issuer_name(cert), data, 256);
+ SU_DEBUG_3((" issuer = %s\n", data));
+ X509_NAME_oneline(X509_get_subject_name(cert), data, 256);
+ SU_DEBUG_3((" subject = %s\n", data));
+ SU_DEBUG_3((" err %i:%s\n", err, X509_verify_cert_error_string(err)));
+ }
- SU_DEBUG_1(("-Error with certificate at depth: %i\n", depth));
- X509_NAME_oneline(X509_get_issuer_name(cert), data, 256);
- SU_DEBUG_1((" issuer = %s\n", data));
- X509_NAME_oneline(X509_get_subject_name(cert), data, 256);
- SU_DEBUG_1((" subject = %s\n", data));
- SU_DEBUG_1((" err %i:%s\n", err, X509_verify_cert_error_string(err)));
}
return ok;
@@ -178,11 +212,14 @@
int tls_init_context(tls_t *tls, tls_issues_t const *ti)
{
static int initialized = 0;
+ int verify;
if (!initialized) {
initialized = 1;
SSL_library_init();
SSL_load_error_strings();
+ tls_ex_data_idx = SSL_get_ex_new_index(0, \
+ "sofia-sip private data", NULL, NULL, NULL);
if (ti->randFile &&
!RAND_load_file(ti->randFile, 1024 * 1024)) {
@@ -267,13 +304,20 @@
return -1;
}
- SSL_CTX_set_verify_depth(tls->ctx, ti->verify_depth);
-
- SSL_CTX_set_verify(tls->ctx,
- ti->verify_peer == 1 ? SSL_VERIFY_PEER : SSL_VERIFY_NONE,
- tls_verify_cb);
+ /* corresponds to (enum tport_tls_verify_policy) */
+ tls->verify_incoming = (ti->policy & 0x1) ? 1 : 0;
+ tls->verify_outgoing = (ti->policy & 0x2) ? 1 : 0;
+ tls->verify_subj_in = (ti->policy & 0x4) ? tls->verify_incoming : 0;
+ tls->verify_subj_out = (ti->policy & 0x8) ? tls->verify_outgoing : 0;
+ tls->verify_date = (ti->verify_date) ? 1 : 0;
+
+ if (tls->verify_incoming)
+ verify = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+ else
+ verify = SSL_VERIFY_NONE;
- tls->verify_incoming = tls->verify_outgoing = ti->verify_peer ? 1 : 0;
+ SSL_CTX_set_verify_depth(tls->ctx, ti->verify_depth);
+ SSL_CTX_set_verify(tls->ctx, verify, tls_verify_cb);
if (!SSL_CTX_set_cipher_list(tls->ctx, ti->cipher)) {
SU_DEBUG_1(("%s: error setting cipher list\n", "tls_init_context"));
@@ -360,13 +404,20 @@
return tls;
}
-tls_t *tls_clone(tls_t *master, int sock, int accept)
+tls_t *tls_init_secondary(tls_t *master, int sock, int accept)
{
tls_t *tls = tls_create(tls_slave);
if (tls) {
tls->ctx = master->ctx;
+ tls->type = master->type;
tls->accept = accept ? 1 : 0;
+ tls->verify_outgoing = master->verify_outgoing;
+ tls->verify_incoming = master->verify_incoming;
+ tls->verify_subj_out = master->verify_subj_out;
+ tls->verify_subj_in = master->verify_subj_in;
+ tls->verify_date = master->verify_date;
+ tls->x509_verified = master->x509_verified;
if (!(tls->read_buffer = su_alloc(tls->home, tls_buffer_size)))
su_home_unref(tls->home), tls = NULL;
@@ -380,7 +431,7 @@
tls->con = SSL_new(tls->ctx);
if (tls->con == NULL) {
- tls_log_errors(1, "tls_clone", 0);
+ tls_log_errors(1, "tls_init_secondary", 0);
tls_free(tls);
errno = EIO;
return NULL;
@@ -388,26 +439,15 @@
SSL_set_bio(tls->con, tls->bio_con, tls->bio_con);
SSL_set_mode(tls->con, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
+ SSL_set_ex_data(tls->con, tls_ex_data_idx, tls);
su_setblocking(sock, 0);
return tls;
}
-tls_t *tls_init_slave(tls_t *master, int sock)
-{
- int accept;
- return tls_clone(master, sock, accept = 1);
-}
-
-tls_t *tls_init_client(tls_t *master, int sock)
-{
- int accept;
- return tls_clone(master, sock, accept = 0);
-}
-
-static
-int tls_post_connection_check(tls_t *tls)
+su_inline
+int tls_post_connection_check(tport_t *self, tls_t *tls)
{
X509 *cert;
int extcount;
@@ -416,13 +456,22 @@
if (!tls) return -1;
cert = SSL_get_peer_certificate(tls->con);
- if (!cert)
- return X509_V_OK;
+ if (!cert) {
+ SU_DEBUG_7(("%s(%p): Peer did not provide X.509 Certificate.\n",
+ __func__, self));
+ if (self->tp_accepted && tls->verify_incoming)
+ return X509_V_ERR_CERT_UNTRUSTED;
+ else if (!self->tp_accepted && tls->verify_outgoing)
+ return X509_V_ERR_CERT_UNTRUSTED;
+ else
+ return X509_V_OK;
+ }
- extcount = X509_get_ext_count(cert);
+ tls->subjects = su_strlst_create(tls->home);
+ if (!tls->subjects)
+ return X509_V_ERR_OUT_OF_MEM;
- if (!tls->subject)
- tls->subject = su_strlst_create(tls->home);
+ extcount = X509_get_ext_count(cert);
/* Find matching subjectAltName.DNS */
for (i = 0; i < extcount; i++) {
@@ -446,13 +495,11 @@
for (j = 0; j < sk_CONF_VALUE_num(values); j++) {
value = sk_CONF_VALUE_value(values, j);
if (strcmp(value->name, "DNS") == 0)
- su_strlst_dup_append(tls->subject, value->value);
- else if (strcmp(value->name, "URI") == 0) {
- char *uri = su_strlst_dup_append(tls->subject, value->value);
- char const *url = strchr(uri, ':');
- if (url++)
- su_strlst_append(tls->subject, url);
- }
+ su_strlst_dup_append(tls->subjects, value->value);
+ if (strcmp(value->name, "IP") == 0)
+ su_strlst_dup_append(tls->subjects, value->value);
+ else if (strcmp(value->name, "URI") == 0)
+ su_strlst_dup_append(tls->subjects, value->value);
}
}
@@ -465,15 +512,15 @@
if (subject) {
if (X509_NAME_get_text_by_NID(subject, NID_commonName,
name, sizeof name) > 0) {
- usize_t k, N = su_strlst_len(tls->subject);
+ usize_t k, N = su_strlst_len(tls->subjects);
name[(sizeof name) - 1] = '\0';
for (k = 0; k < N; k++)
- if (strcasecmp(su_strlst_item(tls->subject, k), name) == 0)
+ if (su_casematch(su_strlst_item(tls->subjects, k), name) == 0)
break;
- if (k == N)
- su_strlst_dup_append(tls->subject, name);
+ if (k >= N)
+ su_strlst_dup_append(tls->subjects, name);
}
}
}
@@ -482,13 +529,64 @@
error = SSL_get_verify_result(tls->con);
- if (error == X509_V_OK)
- tls->verified = 1;
+ if (cert && error == X509_V_OK)
+ tls->x509_verified = 1;
+
+ if (tport_log->log_level >= 7) {
+ int i, len = su_strlst_len(tls->subjects);
+ for (i=0; i < len; i++)
+ SU_DEBUG_7(("%s(%p): Peer Certificate Subject %i: %s\n", \
+ __func__, self, i, su_strlst_item(tls->subjects, i)));
+ if (i == 0)
+ SU_DEBUG_7(("%s(%p): Peer Certificate provided no usable subjects.\n",
+ __func__, self));
+ }
+
+ /* Verify incoming connections */
+ if (self->tp_accepted) {
+ if (!tls->verify_incoming)
+ return X509_V_OK;
+
+ if (!tls->x509_verified)
+ return error;
+
+ if (tls->verify_subj_in) {
+ su_strlst_t const *subjects = self->tp_pri->pri_primary->tp_subjects;
+ int i, items;
+
+ items = subjects ? su_strlst_len(subjects) : 0;
+ if (items == 0)
+ return X509_V_OK;
+
+ for (i=0; i < items; i++) {
+ if (tport_subject_search(su_strlst_item(subjects, i), tls->subjects))
+ return X509_V_OK;
+ }
+ SU_DEBUG_3(("%s(%p): Peer Subject Mismatch (incoming connection)\n", \
+ __func__, self));
+
+ return X509_V_ERR_CERT_UNTRUSTED;
+ }
+ }
+ /* Verify outgoing connections */
+ else {
+ char const *subject = self->tp_canon;
+ if (!tls->verify_outgoing)
+ return X509_V_OK;
+
+ if (!tls->x509_verified || !subject)
+ return error;
+
+ if (tls->verify_subj_out) {
+ if (tport_subject_search(subject, tls->subjects))
+ return X509_V_OK; /* Subject match found in verified certificate chain */
+ SU_DEBUG_3(("%s(%p): Peer Subject Mismatch (%s)\n", \
+ __func__, self, subject));
+
+ return X509_V_ERR_CERT_UNTRUSTED;
+ }
+ }
- if (tls->accept && !tls->verify_incoming)
- return X509_V_OK;
- else if (!tls->accept && !tls->verify_outgoing)
- return X509_V_OK;
return error;
}
@@ -547,7 +645,7 @@
if (0)
SU_DEBUG_1(("tls_read(%p) called on %s (events %u)\n", (void *)tls,
- tls->accept ? "server" : "client",
+ tls->type ? "master" : "slave",
tls->read_events));
if (tls->read_buffer_len)
@@ -607,7 +705,7 @@
if (0)
SU_DEBUG_1(("tls_write(%p, %p, "MOD_ZU") called on %s\n",
(void *)tls, buf, size,
- tls && tls->type == tls_slave ? "server" : "client"));
+ tls && tls->type == tls_slave ? "master" : "slave"));
if (tls == NULL || buf == NULL) {
errno = EINVAL;
@@ -731,7 +829,7 @@
if (self->tp_is_connected == 0) {
int ret, status;
- ret = tls->accept ? SSL_accept(tls->con) : SSL_connect(tls->con);
+ ret = self->tp_accepted ? SSL_accept(tls->con) : SSL_connect(tls->con);
status = SSL_get_error(tls->con, ret);
switch (status) {
@@ -751,7 +849,8 @@
case SSL_ERROR_NONE:
/* TLS Handshake complete */
- if ( tls_post_connection_check(tls) == X509_V_OK ) {
+ status = tls_post_connection_check(self, tls);
+ if ( status == X509_V_OK ) {
su_wait_t wait[1] = {SU_WAIT_INIT};
tport_master_t *mr = self->tp_master;
@@ -770,9 +869,8 @@
tls->read_events = SU_WAIT_IN;
tls->write_events = 0;
self->tp_is_connected = 1;
- self->tp_verified = tls->verified;
- self->tp_subjects = tls->subject == NULL ? NULL :
- su_strlst_dup(self->tp_home, tls->subject);
+ self->tp_verified = tls->x509_verified;
+ self->tp_subjects = tls->subjects;
if (tport_has_queued(self))
tport_send_event(self);
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.h
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.h (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.h Wed Feb 11 11:03:59 2009
@@ -50,9 +50,9 @@
extern char const tls_version[];
typedef struct tls_issues_s {
- int verify_peer; /* 0: no verify certificate, *
- * 1: if fail the TLS/SSL handshake is terminated. */
- int verify_depth; /* if 0, then do nothing */
+ unsigned policy; /* refer to tport_tag.h, tport_tls_verify_policy */
+ unsigned verify_depth;/* if 0, revert to default (2) */
+ unsigned verify_date; /* if 0, notBefore and notAfter dates are ignored */
int configured; /* If non-zero, complain about certificate errors */
char *cert; /* CERT file name. File format is PEM */
char *key; /* Private key file. PEM format */
@@ -78,8 +78,7 @@
} tport_tls_primary_t;
tls_t *tls_init_master(tls_issues_t *tls_issues);
-tls_t *tls_init_slave(tls_t *tls_master, int sock);
-tls_t *tls_init_client(tls_t *tls_master, int sock);
+tls_t *tls_init_secondary(tls_t *tls_master, int sock, int accept);
void tls_free(tls_t *tls);
int tls_get_socket(tls_t *tls);
ssize_t tls_read(tls_t *tls);
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_tls.c
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_tls.c (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_tls.c Wed Feb 11 11:03:59 2009
@@ -95,9 +95,6 @@
static int tport_tls_accept(tport_primary_t *pri, int events);
static tport_t *tport_tls_connect(tport_primary_t *pri, su_addrinfo_t *ai,
tp_name_t const *tpn);
-#if notyet
-static void tport_tls_deliver(tport_t *self, msg_t *msg, su_time_t now);
-#endif
tport_vtable_t const tport_tls_vtable =
{
@@ -171,6 +168,10 @@
char const *path = NULL;
unsigned tls_version = 1;
unsigned tls_verify = 0;
+ unsigned tls_policy = TPTLS_VERIFY_NONE;
+ unsigned tls_depth = 0;
+ unsigned tls_date = 1;
+ su_strlst_t const *tls_subjects = NULL;
su_home_t autohome[SU_HOME_AUTO_SIZE(1024)];
tls_issues_t ti = {0};
@@ -183,6 +184,10 @@
TPTAG_CERTIFICATE_REF(path),
TPTAG_TLS_VERSION_REF(tls_version),
TPTAG_TLS_VERIFY_PEER_REF(tls_verify),
+ TPTAG_TLS_VERIFY_POLICY_REF(tls_policy),
+ TPTAG_TLS_VERIFY_DEPTH_REF(tls_depth),
+ TPTAG_TLS_VERIFY_DATE_REF(tls_date),
+ TPTAG_TLS_VERIFY_SUBJECTS_REF(tls_subjects),
TAG_END());
if (!path) {
@@ -193,8 +198,9 @@
}
if (path) {
- ti.verify_peer = tls_verify;
- ti.verify_depth = 2;
+ ti.policy = tls_policy | (tls_verify ? TPTLS_VERIFY_ALL : 0);
+ ti.verify_depth = tls_depth;
+ ti.verify_date = tls_date;
ti.configured = path != tbf;
ti.randFile = su_sprintf(autohome, "%s/%s", path, "tls_seed.dat");
ti.key = su_sprintf(autohome, "%s/%s", path, "agent.pem");
@@ -225,6 +231,8 @@
return *return_culprit = "tls_init_master", -1;
}
+ if (tls_subjects)
+ pri->pri_primary->tp_subjects = su_strlst_dup(pri->pri_home, tls_subjects);
pri->pri_has_tls = 1;
return 0;
@@ -247,11 +255,9 @@
if (tport_tcp_init_secondary(self, socket, accepted, return_reason) < 0)
return -1;
- if (accepted) {
- tlstp->tlstp_context = tls_init_slave(master, socket);
- if (!tlstp->tlstp_context)
- return *return_reason = "tls_init_slave", -1;
- }
+ tlstp->tlstp_context = tls_init_secondary(master, socket, accepted);
+ if (!tlstp->tlstp_context)
+ return *return_reason = "tls_init_slave", -1;
return 0;
}
@@ -439,20 +445,12 @@
msg_iovec_t iov[],
size_t iovlen)
{
- tport_tls_primary_t *tlspri = (tport_tls_primary_t *)self->tp_pri;
tport_tls_t *tlstp = (tport_tls_t *)self;
enum { TLSBUFSIZE = 2048 };
size_t i, j, n, m, size = 0;
ssize_t nerror;
int oldmask, mask;
- if (tlstp->tlstp_context == NULL) {
- tls_t *master = tlspri->tlspri_master;
- tlstp->tlstp_context = tls_init_client(master, self->tp_socket);
- if (!tlstp->tlstp_context)
- return -1;
- }
-
oldmask = tls_events(tlstp->tlstp_context, self->tp_events);
#if 0
@@ -560,8 +558,6 @@
return 0;
}
else {
- tport_tls_t *tlstp = (tport_tls_t *)self;
- tport_tls_primary_t *tlspri = (tport_tls_primary_t *)self->tp_pri;
int events = SU_WAIT_IN|SU_WAIT_ERR|SU_WAIT_HUP;
SU_CANONIZE_SOCKADDR(su);
@@ -575,8 +571,6 @@
self->tp_conn_orient = 1;
self->tp_is_connected = 0;
- tlstp->tlstp_context = tls_init_slave(tlspri->tlspri_master, s);
-
SU_DEBUG_5(("%s(%p): new connection from " TPN_FORMAT "\n",
__func__, (void *)self, TPN_ARGS(self->tp_name)));
@@ -640,14 +634,9 @@
goto sys_error;
}
- if (tport_setname(self, tpn->tpn_proto, ai, tpn->tpn_canon) != -1
- &&
- tport_register_secondary(self, tls_connect, events) != -1) {
- tport_tls_t *tlstp = (tport_tls_t *)self;
- tport_tls_primary_t *tlspri = (tport_tls_primary_t *)self->tp_pri;
- tlstp->tlstp_context = tls_init_client(tlspri->tlspri_master, s);
- }
- else
+ if (tport_setname(self, tpn->tpn_proto, ai, tpn->tpn_canon) == -1)
+ goto sys_error;
+ else if (tport_register_secondary(self, tls_connect, events) == -1)
goto sys_error;
SU_DEBUG_5(("%s(%p): connecting to " TPN_FORMAT "\n",
1
0
[commit] r11829 - in freeswitch/trunk/libs/sofia-sip: . libsofia-sip-ua/sip
by FreeSWITCH SVN 11 Feb '09
by FreeSWITCH SVN 11 Feb '09
11 Feb '09
Author: mikej
Date: Wed Feb 11 11:03:30 2009
New Revision: 11829
Log:
Thu Jan 15 09:38:34 CST 2009 Bernhard Suttner <bernhard DOT suttner AT comdasys DOT com>
* sip_util.c: fix 484 respose to REFER in sip_response_terminates_dialog()
Asterisk (v 1.2.7.1) does response with 484 if a client does send a refer
with a @ReferTo header to an unknown number. This is therefore not
fundamentally wrong and the dialog should not be destroyed!
Modified:
freeswitch/trunk/libs/sofia-sip/.update
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/sip/sip_util.c
Modified: freeswitch/trunk/libs/sofia-sip/.update
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/.update (original)
+++ freeswitch/trunk/libs/sofia-sip/.update Wed Feb 11 11:03:30 2009
@@ -1 +1 @@
-Wed Feb 11 11:00:10 CST 2009
+Wed Feb 11 11:03:24 CST 2009
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/sip/sip_util.c
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/sip/sip_util.c (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/sip/sip_util.c Wed Feb 11 11:03:30 2009
@@ -1164,14 +1164,25 @@
return 0;
case 484: /* Address Incomplete */
- case 485: /* Ambiguous */
/** @par 484 Address Incomplete and 485 Ambiguous
Similar to 404 and 410, these
responses came to a request whose Request-URI was provided by the
peer in a @Contact header field. Something has gone fundamentally
wrong, and the dialog and all of its usages are destroyed.
- */
+
+ Asterisk (v 1.2.7.1) does response with 484 if a client does send a refer
+ with a @ReferTo header to an unknown number. This is therefore not
+ fundamentally wrong and the dialog should not be destroyed!
+ */
+ if (method == sip_method_refer)
+ {
+ *return_graceful_terminate_usage = 0;
+ return 0;
+ }
+
+ case 485: /* Ambiguous */
+
return terminate_dialog;
case 486: /** @par 486 Busy Here
1
0
11 Feb '09
Author: mikej
Date: Wed Feb 11 11:02:55 2009
New Revision: 11828
Log:
Thu Jan 15 09:33:08 CST 2009 Pekka Pessi <first.last(a)nokia.com>
* Doxyfile.aliases: added @NEW_1_12_11, @VERSION_1_12_11
Modified:
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/docs/Doxyfile.aliases
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/docs/Doxyfile.aliases
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/docs/Doxyfile.aliases (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/docs/Doxyfile.aliases Wed Feb 11 11:02:55 2009
@@ -58,6 +58,8 @@
"NEW_1_12_9=@since New in <a href=\"http://sofia-sip.sf.net/relnotes/relnotes-sofia-sip-1.12.9.txt\">1.12.9</a>" \
"VERSION_1_12_10=<a href=\"http://sofia-sip.sf.net/relnotes/relnotes-sofia-sip-1.12.10.txt\">1.12.10</a>" \
"NEW_1_12_10=@since New in <a href=\"http://sofia-sip.sf.net/relnotes/relnotes-sofia-sip-1.12.10.txt\">1.12.10</a>" \
+ "VERSION_1_12_11=<a href=\"http://sofia-sip.sf.net/relnotes/relnotes-sofia-sip-1.12.11.txt\">1.12.11</a>" \
+ "NEW_1_12_11=@since New in <a href=\"http://sofia-sip.sf.net/relnotes/relnotes-sofia-sip-1.12.11.txt\">1.12.11</a>" \
"VERSION_UNRELEASED=UNRELEASED" \
"NEW_UNRELEASED=@since Not yet released" \
1
0
11 Feb '09
Author: mikej
Date: Wed Feb 11 11:02:34 2009
New Revision: 11827
Log:
Thu Jan 15 08:40:56 CST 2009 Pekka Pessi <first.last(a)nokia.com>
* s2check: added
Added:
freeswitch/trunk/libs/sofia-sip/s2check/
freeswitch/trunk/libs/sofia-sip/s2check/Makefile.am
freeswitch/trunk/libs/sofia-sip/s2check/s2_localinfo.c
freeswitch/trunk/libs/sofia-sip/s2check/s2check.h
freeswitch/trunk/libs/sofia-sip/s2check/s2tcase.c
Modified:
freeswitch/trunk/libs/sofia-sip/configure.ac
Modified: freeswitch/trunk/libs/sofia-sip/configure.ac
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/configure.ac (original)
+++ freeswitch/trunk/libs/sofia-sip/configure.ac Wed Feb 11 11:02:34 2009
@@ -337,6 +337,7 @@
libsofia-sip-ua/url/Doxyfile
libsofia-sip-ua/url/Makefile
libsofia-sip-ua/features/sofia-sip/sofia_features.h
+s2check/Makefile
libsofia-sip-ua-glib/Makefile
libsofia-sip-ua-glib/su-glib/Makefile
libsofia-sip-ua-glib/su-glib/Doxyfile
Added: freeswitch/trunk/libs/sofia-sip/s2check/Makefile.am
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/sofia-sip/s2check/Makefile.am Wed Feb 11 11:02:34 2009
@@ -0,0 +1,37 @@
+#
+# Makefile.am for Sofia-SIP module and unit testing
+#
+# Copyright (C) 2009 Nokia Corporation
+# Contact: Pekka Pessi <pekka.pessi(a)nokia.com>
+# Licensed under LGPL. See file COPYING.
+
+# ----------------------------------------------------------------------
+# Header paths
+
+INCLUDES = $(INTERNAL_INCLUDES)
+
+# ----------------------------------------------------------------------
+# Build targets
+
+noinst_LIBRARIES = libs2.a
+
+# ----------------------------------------------------------------------
+# Rules for building the targets
+
+libs2_a_SOURCES = s2check.h s2tcase.c \
+ s2_localinfo.h s2_localinfo.c
+
+# ----------------------------------------------------------------------
+# Install and distribution rules
+
+EXTRA_DIST =
+
+# ----------------------------------------------------------------------
+# Tests
+
+TESTS =
+
+# ----------------------------------------------------------------------
+# Sofia specific rules
+
+include $(top_srcdir)/rules/sofia.am
Added: freeswitch/trunk/libs/sofia-sip/s2check/s2_localinfo.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/sofia-sip/s2check/s2_localinfo.c Wed Feb 11 11:02:34 2009
@@ -0,0 +1,205 @@
+/*
+ * This file is part of the Sofia-SIP package
+ *
+ * Copyright (C) 2009 Nokia Corporation.
+ *
+ * Contact: Pekka Pessi <pekka.pessi(a)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 s2_localinfo.c
+ *
+ * @brief s2_localinfo() stub returning well-known addresses for testing.
+ *
+ * @author Pekka Pessi <Pekka.Pessi(a)nokia.com>
+ */
+
+#include "config.h"
+
+#include <sofia-sip/hostdomain.h>
+#include <sofia-sip/su_string.h>
+#include <sofia-sip/su_alloc.h>
+
+#include <stdlib.h>
+#include <assert.h>
+
+#define SU_LOCALINFO_TEST 1
+
+#define su_getlocalinfo s2_getlocalinfo
+#define su_freelocalinfo s2_freelocalinfo
+#define su_gli_strerror s2_gli_strerror
+#define su_copylocalinfo s2_copylocalinfo
+#define su_sockaddr_scope s2_sockaddr_scope
+#define su_getlocalip s2_getlocalip
+
+#include "su_localinfo.c"
+
+static char const *default_ifaces[] = {
+ "lo0\0" "127.0.0.1\0" "::1\0",
+ NULL
+};
+
+static char const **ifaces = default_ifaces;
+
+void s2_localinfo_ifaces(char const **replace_ifaces)
+{
+ ifaces = replace_ifaces;
+}
+
+int
+s2_getlocalinfo(su_localinfo_t const *hints,
+ su_localinfo_t **return_localinfo)
+{
+ int error = 0, ip4 = 0, ip6 = 0, i;
+ su_localinfo_t *result = NULL, **rr = &result;
+ su_localinfo_t hh[1] = {{ 0 }};
+
+ assert(return_localinfo);
+
+ *return_localinfo = NULL;
+
+ if (hints) {
+ /* Copy hints so that it can be modified */
+ *hh = *hints;
+ if (hh->li_canonname)
+ hh->li_flags |= LI_CANONNAME;
+ }
+
+ hints = hh;
+
+ switch (hh->li_family) {
+#if SU_HAVE_IN6
+ case AF_INET6:
+ if (hh->li_flags & LI_V4MAPPED)
+ ip6 = ip4 = 1, hh->li_family = 0;
+ else
+ ip6 = 1;
+ break;
+#endif
+
+ case AF_INET:
+ ip4 = 1;
+ break;
+
+ case 0:
+ ip6 = ip4 = 1;
+ break;
+
+ default:
+ return -1;
+ }
+
+ for (i = 0; ifaces[i]; i++) {
+ char const *iface = ifaces[i], *address = iface;
+ su_sockaddr_t su[1];
+
+ for (;(address += strlen(address) + 1)[0];) {
+ su_localinfo_t *li = NULL;
+ int scope = 0;
+
+ memset(su, 0, sizeof su);
+
+ if (0)
+ ;
+#if SU_HAVE_IN6
+ else if (ip4 &&
+ (hints->li_flags & LI_V4MAPPED) != 0 &&
+ host_is_ip4_address(address)) {
+ int32_t mapped;
+ su->su_len = (sizeof su->su_sin6);
+ su_inet_pton(su->su_family = AF_INET6,
+ address,
+ &mapped);
+ ((int32_t*)&su->su_sin6.sin6_addr)[2] = htonl(0xffff);
+ ((int32_t*)&su->su_sin6.sin6_addr)[3] = mapped;
+ scope = li_scope4(mapped);
+ }
+ else if (ip6 && host_is_ip6_address(address)) {
+ su->su_len = (sizeof su->su_sin6);
+ su_inet_pton(su->su_family = AF_INET6,
+ address,
+ &su->su_sin6.sin6_addr);
+ scope = li_scope6(&su->su_sin6.sin6_addr);
+ }
+#endif
+ else if (ip4 && host_is_ip4_address(address)) {
+ su->su_len = (sizeof su->su_sin);
+ su_inet_pton(su->su_family = AF_INET,
+ address,
+ &su->su_sin.sin_addr);
+ scope = li_scope4(su->su_sin.sin_addr.s_addr);
+ }
+ else
+ continue;
+
+ if (scope == 0)
+ continue;
+ if (hints->li_scope && (hints->li_scope & scope) == 0)
+ continue;
+ if (hints->li_index && hints->li_index != i + 1)
+ continue;
+ if (hints->li_ifname && strcmp(hints->li_ifname, iface) != 0)
+ continue;
+ if (hints->li_family && hints->li_family != su->su_family)
+ continue;
+ if (hints->li_canonname && !su_casematch(address, hints->li_canonname))
+ continue;
+
+ li = calloc(1, (sizeof *li) + (sizeof *su) + strlen(iface) + 1);
+ li->li_family = su->su_family;
+ li->li_scope = scope;
+ li->li_index = i + 1;
+ li->li_addrlen = su_sockaddr_size(su);
+ li->li_addr = memcpy((li + 1), su, (sizeof *su));
+ if (hints->li_flags & LI_IFNAME)
+ li->li_ifname = strcpy((char *)li->li_addr + li->li_addrlen, iface);
+
+ if ((hints->li_flags & LI_CANONNAME) || hints->li_canonname) {
+ li->li_flags |= LI_NUMERIC;
+ li->li_canonname = su_strdup(NULL, address);
+ }
+
+#define LI_MAPPED(li) \
+ ((li)->li_family == AF_INET6 && \
+ (IN6_IS_ADDR_V4MAPPED(&(li)->li_addr->su_sin6.sin6_addr) || \
+ IN6_IS_ADDR_V4COMPAT(&(li)->li_addr->su_sin6.sin6_addr)))
+
+ /* Insert according to scope, mappedness and family */
+ for (rr = &result; *rr; rr = &(*rr)->li_next) {
+ if ((*rr)->li_scope < li->li_scope)
+ break;
+#if SU_HAVE_IN6
+ if (LI_MAPPED(*rr) > LI_MAPPED(li))
+ break;
+#endif
+ if ((*rr)->li_family < li->li_family)
+ break;
+ }
+ li->li_next = *rr;
+ *rr = li;
+ }
+ }
+
+ *return_localinfo = result;
+
+ if (result == NULL)
+ error = ELI_NOADDRESS;
+
+ return error;
+}
+
Added: freeswitch/trunk/libs/sofia-sip/s2check/s2check.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/sofia-sip/s2check/s2check.h Wed Feb 11 11:02:34 2009
@@ -0,0 +1,50 @@
+/*
+ * This file is part of the Sofia-SIP package
+ *
+ * Copyright (C) 2009 Nokia Corporation.
+ *
+ * Contact: Pekka Pessi <pekka.pessi(a)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 S2CHECK_H
+/** Defined when <s2check.h> has been included. */
+#define S2CHECK_H
+
+/**@internal @file s2check.h
+ *
+ * @brief Check-based testing
+ *
+ * @author Pekka Pessi <Pekka.Pessi(a)nokia.com>
+ */
+
+#include <check.h>
+
+SOFIA_BEGIN_DECLS
+
+#undef tcase_add_test
+/* Redirect tcase_add_test() to our function */
+#define tcase_add_test(tc, tf) s2_tcase_add_test(tc, tf, "" #tf "")
+
+void s2_tcase_add_test(TCase *, TFun, char const *name);
+
+
+
+SOFIA_END_DECLS
+
+#endif /* S2CHECK_H */
Added: freeswitch/trunk/libs/sofia-sip/s2check/s2tcase.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/sofia-sip/s2check/s2tcase.c Wed Feb 11 11:02:34 2009
@@ -0,0 +1,104 @@
+/*
+ * This file is part of the Sofia-SIP package
+ *
+ * Copyright (C) 2009 Nokia Corporation.
+ *
+ * Contact: Pekka Pessi <pekka.pessi(a)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
+ *
+ */
+
+#include "config.h"
+
+#if HAVE_CHECK
+
+#if HAVE_FNMATCH_H
+#include <fnmatch.h>
+#endif
+
+static char const * const default_patterns[] = { "*", NULL };
+static char const * const *test_patterns = default_patterns;
+
+#undef tcase_add_test
+
+/** tcase_add_test() replacement.
+ *
+ * A special version of tcase_add_test() that inserts test function into
+ * tcase only if its name matches given pattern.
+ */
+void s2_tcase_add_test(TCase *tc, TFun tf, char const *name)
+{
+ char const * const *patterns;
+
+#if HAVE_FNMATCH_H
+ for (patterns = test_patterns; *patterns; patterns++) {
+ if (!fnmatch(*patterns, name, 0)) {
+ if (strcmp(*patterns, "*")) {
+ printf("%s: running\n", name);
+ }
+ tcase_add_test(tc, tf, name, 0, 0, 1);
+ return;
+ }
+ }
+#else
+ for (patterns = test_patterns; *patterns; patterns++) {
+ if (!strcmp(*patterns, name) || !strcmp(*patterns, "*")) {
+ if (strcmp(*patterns, "*")) {
+ printf("%s: running\n", name);
+ }
+ tcase_add_test(tc, tf, name, 0, 0, 1);
+ return;
+ }
+ }
+#endif
+}
+
+/** Select tests based on pattern.
+ *
+ * Allow easy selection of test cases to run. Pattern can be a shell glob,
+ * or consists of multiple comma-separated patterns.
+ */
+void s2_select_tests(char const *pattern)
+{
+ size_t i;
+ char *cases, *s, **patterns;
+
+ if (!pattern)
+ return;
+
+ cases = strdup(pattern);
+
+ /* Count commas */
+ for (i = 2, s = cases; (s = strchr(s, ',')); s++)
+ i++;
+
+ patterns = calloc(i, sizeof *patterns);
+
+ /* Split by commas */
+ for (i = 0, s = cases;; i++) {
+ patterns[i] = s;
+ if (s == NULL)
+ break;
+ s = strchr(s, ',');
+ if (s)
+ *s++ = '\0';
+ }
+
+ test_patterns = (char const * const *)patterns;
+}
+
+#endif /* HAVE_CHECK */
1
0