Commit 3fa572b2 authored by jehan's avatar jehan
Browse files

multi proxy management

parent 3b025def
......@@ -272,7 +272,7 @@ static void register_response_event(void *user_ctx, const belle_sip_response_eve
if (op->registration_refresh_timer>0) {
belle_sip_main_loop_cancel_source(belle_sip_stack_get_main_loop(op->base.root->stack),op->registration_refresh_timer);
}
op->registration_refresh_timer = belle_sip_main_loop_add_timeout(belle_sip_stack_get_main_loop(op->base.root->stack),(belle_sip_source_func_t)register_refresh,op,belle_sip_header_expires_get_expires(expires_header)*1000);
op->registration_refresh_timer = belle_sip_main_loop_add_timeout(belle_sip_stack_get_main_loop(op->base.root->stack),(belle_sip_source_func_t)register_refresh,op,expires*1000);
}
sal_remove_pending_auth(op->base.root,op);/*just in case*/
break;
......
......@@ -794,7 +794,8 @@ static void ping_reply(SalOp *op){
ms_warning("ping reply without call attached...");
}
}
static bool_t auth_requested(SalOp*op, SalAuthInfo* sai) {
static bool_t fill_auth_info(SalOp*op, SalAuthInfo* sai) {
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
LinphoneAuthInfo *ai=(LinphoneAuthInfo*)linphone_core_find_auth_info(lc,sai->realm,sai->username);
if (ai) {
......@@ -807,6 +808,20 @@ static bool_t auth_requested(SalOp*op, SalAuthInfo* sai) {
return FALSE;
}
}
static bool_t auth_requested(SalOp*op, SalAuthInfo* sai) {
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
if (fill_auth_info(op,sai)) {
return TRUE;
} else {
if (lc->vtable.auth_info_requested) {
lc->vtable.auth_info_requested(lc,sai->realm,sai->username);
if (fill_auth_info(op,sai)) {
return TRUE;
}
}
return FALSE;
}
}
SalCallbacks linphone_sal_callbacks={
call_received,
call_ringing,
......
......@@ -4144,7 +4144,7 @@ void sip_config_uninit(LinphoneCore *lc)
MSList *elem;
int i;
sip_config_t *config=&lc->sip_conf;
bool_t all_unregistered=FALSE;
bool_t still_registered=TRUE;
lp_config_set_int(lc->config,"sip","guess_hostname",config->guess_hostname);
lp_config_set_string(lc->config,"sip","contact",config->contact);
......@@ -4162,11 +4162,12 @@ void sip_config_uninit(LinphoneCore *lc)
linphone_proxy_config_edit(cfg); /* to unregister */
}
for (i=0;i<20&&!all_unregistered;i++){
for (i=0;i<20&&still_registered;i++){
still_registered=FALSE;
sal_iterate(lc->sal);
for(elem=config->proxies;elem!=NULL;elem=ms_list_next(elem)){
LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)(elem->data);
all_unregistered|=!linphone_proxy_config_is_registered(cfg);
still_registered|=linphone_proxy_config_is_registered(cfg);
}
#ifndef WIN32
usleep(100000);
......
##
## This is the default Flexisip configuration file
##
##
## Some global settings of the flexisip proxy.
##
[global]
# Outputs very detailed logs
# Default value: false
debug=false
# List of white space separated host names pointing to this machine.
# This is to prevent loops while routing SIP messages.
# Default value: localhost
aliases=auth.example.org auth1.example.org auth2.example.org sip.example.org
# The public ip address of the proxy.
# Default value: guess
ip-address=guess
# The local interface's ip address where to listen. The wildcard
# (*) means all interfaces.
# Default value: *
bind-address=sip.example.org
# UDP/TCP port number to listen for sip messages.
# Default value: 5060
port=5060
##
## TLS specific parameters.
##
[tls]
# Enable SIP/TLS (sips)
# Default value: true
enabled=true
# The port used for SIP/TLS
# Default value: 5061
port=5061
# An absolute path of a directory where TLS certificate can be found.
# The private key for TLS server must be in a agent.pem file within
# this directory
# Default value: /etc/flexisip/tls
certificates-dir=/Users/jehanmonnier/workspaces/workspace-macosx/flexisip
##
## STUN server parameters.
##
[stun-server]
# Enable or disable stun server.
# Default value: true
enabled=true
# STUN server port number.
# Default value: 3478
port=3478
##
## The NatHelper module executes small tasks to make SIP work smoothly
## despite firewalls.It corrects the Contact headers that contain
## obviously inconsistent addresses, and adds a Record-Route to ensure
## subsequent requests are routed also by the proxy, through the
## UDP or TCP channel each client opened to the proxy.
##
[module::NatHelper]
# Indicate whether the module is activated.
# Default value: true
enabled=false
# List of domain names in sip from allowed to enter the module.
# Default value: *
from-domains=*
# List of domain names in sip to allowed to enter the module.
# Default value: *
to-domains=*
##
## The authentication module challenges SIP requests according to
## a user/password database.
##
[module::Authentication]
# Indicate whether the module is activated.
# Default value: false
enabled=true
# List of domain names in sip from allowed to enter the module.
# Default value: *
from-domains=auth.example.org auth1.example.org auth2.example.org
# List of domain names in sip to allowed to enter the module.
# Default value: *
to-domains=*
# List of whitespace separated domain names to challenge. Others
# are denied.
# Default value:
auth-domains=auth.example.org auth1.example.org auth2.example.org
# List of whitespace separated IP which will not be challenged.
# Default value:
trusted-hosts=
# Database backend implementation [odbc, file].
# Default value: odbc
db-implementation=file
# Odbc connection string to use for connecting to database. ex1:
# DSN=myodbc3; where 'myodbc3' is the datasource name. ex2: DRIVER={MySQL};SERVER=localhost;DATABASE=dbname;USER=username;PASSWORD=passname;OPTION=3;
# for a DSN-less connection. ex3: /etc/flexisip/passwd; for a file
# containing one 'user@domain password' by line.
# Default value:
datasource=./userdb.conf
# Odbc SQL request to execute to obtain the password. Named parameters
# are :id, :domain and :authid.'
# Default value: select password from accounts where id = :id and domain = :domain and authid=:authid
request=select password from accounts where id = :id and domain = :domain and authid=:authid
# Maximum length of the login column in database.
# Default value: 100
max-id-length=100
# Maximum length of the password column in database
# Default value: 100
max-password-length=100
# Use pooling in odbc
# Default value: true
odbc-pooling=true
# Display timing statistics after this count of seconds
# Default value: 0
odbc-display-timings-interval=0
# Display timing statistics once the number of samples reach this
# number.
# Default value: 0
odbc-display-timings-after-count=0
# Retrieve passwords asynchronously.
# Default value: false
odbc-asynchronous=false
# Duration of the validity of the credentials added to the cache
# in seconds.
# Default value: 1800
cache-expire=1800
# Retrieve password immediately so that it is cached when an authenticated
# request arrives.
# Default value: true
immediate-retrieve-password=true
# True if the passwords retrieved from the database are already
# SIP hashed (HA1=MD5(A1)=MD5(username:realm:password)).
# Default value: false
hashed-passwords=false
##
## The Registrar module accepts REGISTERs for domains it manages,
## and store the address of record in order to route other requests
## destinated to the client who registered.
##
[module::Registrar]
# Indicate whether the module is activated.
# Default value: true
enabled=true
# List of domain names in sip from allowed to enter the module.
# Default value: *
from-domains=auth.example.org auth1.example.org auth2.example.org sip.example.org
# List of domain names in sip to allowed to enter the module.
# Default value: *
to-domains=*
# List of whitelist separated domain names to be managed by the
# registrar.
# Default value: localhost
reg-domains=auth.example.org auth1.example.org auth2.example.org sip.example.org
##
## The purpose of the ContactRouteInserter module is to masquerade
## the contact header of incoming registers that are not handled
## locally (think about flexisip used as a SBC gateway) in such a
## way that it is then possible to route back outgoing invites to
## the original address. It is a kind of similar mechanism as Record-Route,
## but for REGISTER.
##
[module::ContactRouteInserter]
# Indicate whether the module is activated.
# Default value: true
enabled=false
# List of domain names in sip from allowed to enter the module.
# Default value: *
from-domains=*
# List of domain names in sip to allowed to enter the module.
# Default value: *
to-domains=*
# Hack for workarounding Nortel CS2k gateways bug.
# Default value: false
masquerade-contacts-for-invites=false
##
## This module performs load balancing between a set of configured
## destination proxies.
##
[module::LoadBalancer]
# Indicate whether the module is activated.
# Default value: false
enabled=false
# List of domain names in sip from allowed to enter the module.
# Default value: *
from-domains=*
# List of domain names in sip to allowed to enter the module.
# Default value: *
to-domains=*
# Whitespace separated list of sip routes to balance the requests.
# Example: <sip:192.168.0.22> <sip:192.168.0.23>
# Default value:
routes=
##
## The MediaRelay module masquerades SDP message so that all RTP
## and RTCP streams go through the proxy. The RTP and RTCP streams
## are then routed so that each client receives the stream of the
## other. MediaRelay makes sure that RTP is ALWAYS established, even
## with uncooperative firewalls.
##
[module::MediaRelay]
# Indicate whether the module is activated.
# Default value: true
enabled=false
# List of domain names in sip from allowed to enter the module.
# Default value: *
from-domains=*
# List of domain names in sip to allowed to enter the module.
# Default value: *
to-domains=*
##
## The purpose of the Transcoder module is to transparently transcode
## from one audio codec to another to make the communication possible
## between clients that do not share the same set of supported codecs.
## Concretely it adds all missing codecs into the INVITEs it receives,
## and adds codecs matching the original INVITE into the 200Ok. Rtp
## ports and addresses are masqueraded so that the streams can be
## processed by the proxy. The transcoding job is done in the background
## by the mediastreamer2 library, as consequence the set of supported
## codecs is exactly the the same as the codec set supported by mediastreamer2,
## including the possible plugins you may installed to extend mediastreamer2.
## WARNING: this module can conflict with the MediaRelay module as
## both are changin the SDP. Make sure to configure them with different
## to-domains or from-domains filter if you want to enable both of
## them.
##
[module::Transcoder]
# Indicate whether the module is activated.
# Default value: false
enabled=true
# List of domain names in sip from allowed to enter the module.
# Default value: *
from-domains=freephonie.net
# List of domain names in sip to allowed to enter the module.
# Default value: *
to-domains=freephonie.net
# Nominal size of RTP jitter buffer, in milliseconds. A value of
# 0 means no jitter buffer (packet processing).
# Default value: 0
jb-nom-size=0
# Whitespace separated list of user-agent strings for which audio
# rate control is performed.
# Default value:
rc-user-agents=
# Whitespace seprated list of audio codecs, in order of preference.
# Default value: speex/8000 amr/8000 iLBC/8000 gsm/8000 pcmu/8000 pcma/8000
#audio-codecs=speex/8000 amr/8000 iLBC/8000 gsm/8000 pcmu/8000 pcma/8000 telephone-event/8000
audio-codecs=amr/8000 pcmu/8000 pcma/8000 telephone-event/8000
##
## This module executes the basic routing task of SIP requests and
## pass them to the transport layer. It must always be enabled.
##
[module::Forward]
# Indicate whether the module is activated.
# Default value: true
enabled=true
# List of domain names in sip from allowed to enter the module.
# Default value: *
from-domains=*
# List of domain names in sip to allowed to enter the module.
# Default value: *
to-domains=*
# A sip uri where to send all requests
# Default value:
#route=<sip:sip.linphone.org>
# Rewrite request-uri's host and port according to above route
# Default value: false
rewrite-req-uri=false
......@@ -88,19 +88,12 @@ static void registration_state_changed(struct _LinphoneCore *lc, LinphoneProxyCo
}
static void auth_info_requested(LinphoneCore *lc, const char *realm, const char *username) {
ms_message("Auth info requested for user id [%s] at realm [%s]\n"
,username
,realm);
number_of_auth_info_requested++;
}
static LinphoneCore* create_lc() {
LinphoneCoreVTable v_table;
memset (&v_table,0,sizeof(v_table));
v_table.registration_state_changed=registration_state_changed;
v_table.auth_info_requested=auth_info_requested;
return linphone_core_new(&v_table,NULL,NULL,NULL);
}
static void register_with_refresh(LinphoneCore* lc, bool_t refresh,const char* domain,const char* route) {
......@@ -161,14 +154,57 @@ static void simple_register(){
CU_ASSERT_EQUAL(number_of_auth_info_requested,0);
}
static void simple_authenticated_register(){
number_of_auth_info_requested=0;
LinphoneCore* lc = create_lc();
LinphoneAuthInfo *info=linphone_auth_info_new(test_username,NULL,test_password,NULL,auth_domain); /*create authentication structure from identity*/
linphone_core_add_auth_info(lc,info); /*add authentication info to LinphoneCore*/
register_with_refresh(lc,FALSE,auth_domain,NULL);
CU_ASSERT_EQUAL(number_of_auth_info_requested,0);
}
static void auth_info_requested(LinphoneCore *lc, const char *realm, const char *username) {
ms_message("Auth info requested for user id [%s] at realm [%s]\n"
,username
,realm);
number_of_auth_info_requested++;
LinphoneAuthInfo *info=linphone_auth_info_new(test_username,NULL,test_password,NULL,auth_domain); /*create authentication structure from identity*/
linphone_core_add_auth_info(lc,info); /*add authentication info to LinphoneCore*/
}
static void authenticated_register_with_no_initial_credentials(){
number_of_auth_info_requested=0;
LinphoneCoreVTable v_table;
LinphoneCore* lc;
memset (&v_table,0,sizeof(v_table));
v_table.registration_state_changed=registration_state_changed;
v_table.auth_info_requested=auth_info_requested;
lc = linphone_core_new(&v_table,NULL,NULL,NULL);
register_with_refresh(lc,FALSE,auth_domain,NULL);
CU_ASSERT_EQUAL(number_of_auth_info_requested,1);
}
static void multiple_proxy(){
LinphoneCoreVTable v_table;
LinphoneCore* lc;
int retry=0;
memset (&v_table,0,sizeof(v_table));
reset_counters();
v_table.registration_state_changed=registration_state_changed;
lc = linphone_core_new(&v_table,NULL,"./multi_account_lrc",NULL);
CU_ASSERT_EQUAL(ms_list_size(linphone_core_get_proxy_config_list(lc)),3);
while (number_of_LinphoneRegistrationOk<3 && retry++ <20) {
linphone_core_iterate(lc);
ms_usleep(100000);
}
CU_ASSERT_EQUAL(number_of_LinphoneRegistrationOk,3);
linphone_core_destroy(lc);
}
int init_test_suite () {
CU_pSuite pSuite = CU_add_suite("liblinphone init test suite", init, uninit);
......@@ -185,6 +221,12 @@ CU_pSuite pSuite = CU_add_suite("liblinphone init test suite", init, uninit);
if (NULL == CU_add_test(pSuite, "simple register with digest auth tester", simple_authenticated_register)) {
return CU_get_error();
}
if (NULL == CU_add_test(pSuite, "register with digest auth tester without initial credentials", authenticated_register_with_no_initial_credentials)) {
return CU_get_error();
}
if (NULL == CU_add_test(pSuite, "multi account", multiple_proxy)) {
return CU_get_error();
}
return 0;
}
int main (int argc, char *argv[]) {
......
[sip]
sip_port=5072
sip_tcp_port=5072
sip_tls_port=5073
[auth_info_0]
username=liblinphone_tester
userid=liblinphone_tester
passwd=secret
realm="auth.example.org"
[auth_info_1]
username=liblinphone_tester
userid=liblinphone_tester
passwd=secret
realm="auth1.example.org"
[auth_info_2]
username=liblinphone_tester
userid=liblinphone_tester
passwd=secret
realm="auth2.example.org"
[proxy_0]
reg_proxy=auth.example.org
reg_identity=sip:liblinphone_tester@auth.example.org
reg_expires=3600
reg_sendregister=1
publish=0
dial_escape_plus=0
[proxy_1]
reg_proxy=auth.example.org
reg_identity=sip:liblinphone_tester@auth1.example.org
reg_expires=3600
reg_sendregister=1
publish=0
dial_escape_plus=0
[proxy_2]
reg_proxy=auth.example.org
reg_identity=sip:liblinphone_tester@auth2.example.org
reg_expires=3600
reg_sendregister=1
publish=0
dial_escape_plus=0
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment