mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-02-07 14:18:25 +00:00
multi proxy management
This commit is contained in:
parent
3b025defd5
commit
3fa572b262
6 changed files with 452 additions and 13 deletions
|
|
@ -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);
|
||||
|
|
|
|||
333
tester/flexisip.conf
Normal file
333
tester/flexisip.conf
Normal file
|
|
@ -0,0 +1,333 @@
|
|||
##
|
||||
## 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[]) {
|
||||
|
|
|
|||
48
tester/multi_account_lrc
Normal file
48
tester/multi_account_lrc
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
[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
|
||||
|
||||
|
||||
Loading…
Add table
Reference in a new issue