- improvements on RTP proxy for proxying a "looped" call
(means originating from local UA , via external registrar back to another local UA)
This commit is contained in:
parent
f303dd3b5d
commit
f6b0b49bf9
@ -1,6 +1,9 @@
|
||||
0.6.0
|
||||
=====
|
||||
29-May-2007: - Deal with PRACK requests (RFC3262)
|
||||
- improvements on RTP proxy for proxying a "looped" call
|
||||
(means originating from local UA , via external registrar
|
||||
back to another local UA)
|
||||
25-May-2007: - Just discovered some patches originating from Debian
|
||||
project - included most of them as they make sense.
|
||||
(Hint: People, if you get fixes, please drop me a note
|
||||
|
||||
52
src/proxy.c
52
src/proxy.c
@ -817,28 +817,15 @@ int proxy_rewrite_invitation_body(sip_ticket_t *ticket, int direction){
|
||||
*/
|
||||
sts = osip_message_get_body(mymsg, 0, &body);
|
||||
if (sts != 0) {
|
||||
#if 0
|
||||
if ((MSG_IS_RESPONSE_FOR(mymsg,"INVITE")) &&
|
||||
(MSG_IS_STATUS_1XX(mymsg))) {
|
||||
/* 1xx responses *MAY* contain SDP data */
|
||||
DEBUGC(DBCLASS_PROXY, "rewrite_invitation_body: "
|
||||
"no body found in message");
|
||||
return STS_SUCCESS;
|
||||
} else {
|
||||
/* INVITE request and 200 response *MUST* contain SDP data */
|
||||
ERROR("rewrite_invitation_body: no body found in message");
|
||||
return STS_FAILURE;
|
||||
}
|
||||
#else
|
||||
DEBUGC(DBCLASS_PROXY, "rewrite_invitation_body: "
|
||||
"no body found in message");
|
||||
return STS_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
sts = sip_body_to_str(body, &buff, &buflen);
|
||||
if (sts != 0) {
|
||||
ERROR("rewrite_invitation_body: unable to sip_body_to_str");
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
DEBUGC(-1, "rewrite_invitation_body: payload %ld bytes", (long)buflen);
|
||||
@ -1017,8 +1004,8 @@ if (configuration.debuglevel)
|
||||
if (sdp_message_m_port_get(sdp, media_stream_no)) {
|
||||
msg_port=atoi(sdp_message_m_port_get(sdp, media_stream_no));
|
||||
if ((msg_port > 0) && (msg_port <= 65535)) {
|
||||
char *client_id=NULL;
|
||||
static char from_string[HOSTNAME_SIZE];
|
||||
client_id_t client_id;
|
||||
osip_contact_t *contact = NULL;
|
||||
char *tmp=NULL;
|
||||
char *protocol=NULL;
|
||||
|
||||
@ -1028,10 +1015,35 @@ if (configuration.debuglevel)
|
||||
* particular Header (Contact) or not.
|
||||
* I should just go for the remote IP address here, no?
|
||||
*/
|
||||
tmp=utils_inet_ntoa(ticket->from.sin_addr);
|
||||
strncpy(from_string, tmp, HOSTNAME_SIZE);
|
||||
from_string[HOSTNAME_SIZE-1]='\0';
|
||||
client_id=from_string;
|
||||
/* &&& NO, using the sender IP will cause troubles if
|
||||
* the remote peer (Proxy/registrar) is thrown out of
|
||||
* the signalling path. Then suddenly the IP address changes.
|
||||
*
|
||||
* I should probably go back to the Contact Header based idea,
|
||||
* with fallback to IP.
|
||||
* I must use a n-item structure, including all things that
|
||||
* can be used for comparing. Then, in the RTP proxy, comparison
|
||||
* must take place according to priorities with the item
|
||||
* with highest priority present in the RTP table *and*
|
||||
* extracted from the SIP message.
|
||||
* To start with, this can be just 2 things, the Contact header
|
||||
* and the Layer 3 IP address. As long as the UAs include the
|
||||
* Contact header, we survive IP changes (e.g. when the SIP
|
||||
* Registrar/Proxy is removed from signalling path within an
|
||||
* ongoing call. This may happen if the Registrar/Proxy does
|
||||
* not explicitely ask to stay in the signalling path using
|
||||
* Record-Route headers - which is perfectly legal
|
||||
*
|
||||
*/
|
||||
|
||||
/* get the Contact Header if present */
|
||||
osip_message_get_contact(mymsg, 0, &contact);
|
||||
osip_contact_to_str(contact, &tmp);
|
||||
strcpy(client_id.contact, tmp);
|
||||
|
||||
/* store the IP address of the sender */
|
||||
memcpy(&client_id.from_ip, &ticket->from.sin_addr,
|
||||
sizeof(client_id.from_ip));
|
||||
|
||||
/*
|
||||
* is this an RTP stream ? If yes, set 'isrtp=1'
|
||||
|
||||
@ -72,7 +72,7 @@ int rtpproxy_init( void ) {
|
||||
* STS_SUCCESS on success
|
||||
* STS_FAILURE on error
|
||||
*/
|
||||
int rtp_start_fwd (osip_call_id_t *callid, char *client_id,
|
||||
int rtp_start_fwd (osip_call_id_t *callid, client_id_t client_id,
|
||||
int direction, int media_stream_no,
|
||||
struct in_addr local_ipaddr, int *local_port,
|
||||
struct in_addr remote_ipaddr, int remote_port,
|
||||
|
||||
@ -22,7 +22,6 @@
|
||||
|
||||
#define CALLIDNUM_SIZE 256
|
||||
#define CALLIDHOST_SIZE 128
|
||||
#define CLIENT_ID_SIZE 128
|
||||
|
||||
typedef struct {
|
||||
struct timeval starttime ;
|
||||
@ -42,11 +41,11 @@ typedef struct {
|
||||
typedef struct {
|
||||
int rtp_rx_sock; /* rx socket (0 -> free slot)*/
|
||||
int rtp_tx_sock; /* tx socket */
|
||||
int rtp_con_rx_sock; /* rx socket rtcp */
|
||||
int rtp_con_tx_sock; /* tx socket rtcp */
|
||||
int rtp_con_rx_sock; /* rx socket rtcp */
|
||||
int rtp_con_tx_sock; /* tx socket rtcp */
|
||||
char callid_number[CALLIDNUM_SIZE]; /* call ID */
|
||||
char callid_host[CALLIDHOST_SIZE]; /* --"-- */
|
||||
char client_id[CLIENT_ID_SIZE];
|
||||
client_id_t client_id;
|
||||
int direction; /* Direction of RTP stream */
|
||||
int media_stream_no;
|
||||
timecontrol_t tc;
|
||||
@ -62,7 +61,7 @@ typedef struct {
|
||||
* RTP relay
|
||||
*/
|
||||
int rtp_relay_init(void);
|
||||
int rtp_relay_start_fwd (osip_call_id_t *callid, char *client_id,
|
||||
int rtp_relay_start_fwd (osip_call_id_t *callid, client_id_t client_id,
|
||||
int rtp_direction, int media_stream_no,
|
||||
struct in_addr local_ipaddr, int *local_port,
|
||||
struct in_addr remote_ipaddr, int remote_port,
|
||||
|
||||
@ -441,7 +441,7 @@ static void *rtpproxy_main(void *arg) {
|
||||
* STS_SUCCESS on success
|
||||
* STS_FAILURE on error
|
||||
*/
|
||||
int rtp_relay_start_fwd (osip_call_id_t *callid, char *client_id,
|
||||
int rtp_relay_start_fwd (osip_call_id_t *callid, client_id_t client_id,
|
||||
int rtp_direction,
|
||||
int media_stream_no, struct in_addr local_ipaddr,
|
||||
int *local_port, struct in_addr remote_ipaddr,
|
||||
@ -461,11 +461,6 @@ int rtp_relay_start_fwd (osip_call_id_t *callid, char *client_id,
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
if (client_id == NULL) {
|
||||
ERROR("rtp_relay_start_fwd: did not get a client ID!");
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* life insurance: check size of received call_id strings
|
||||
* I don't know what the maximum allowed size within SIP is,
|
||||
@ -484,16 +479,10 @@ int rtp_relay_start_fwd (osip_call_id_t *callid, char *client_id,
|
||||
callid->host, (long)strlen(callid->host),CALLIDHOST_SIZE);
|
||||
return STS_FAILURE;
|
||||
}
|
||||
if (client_id && (strlen(client_id) >= CLIENT_ID_SIZE)) {
|
||||
ERROR("rtp_relay_start_fwd: client ID [%s] has too many characters "
|
||||
"(%ld, max=%i)",
|
||||
client_id, (long)strlen(client_id),CLIENT_ID_SIZE);
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
DEBUGC(DBCLASS_RTP,"rtp_relay_start_fwd: starting RTP proxy "
|
||||
"stream for: %s@%s[%s] (%s) #=%i",
|
||||
callid->number, callid->host, client_id,
|
||||
"stream for: CallID=%s@%s [Client-ID=%s] (%s) #=%i",
|
||||
callid->number, callid->host, client_id.contact,
|
||||
((rtp_direction == DIR_INCOMING) ? "incoming RTP" : "outgoing RTP"),
|
||||
media_stream_no);
|
||||
|
||||
@ -522,7 +511,8 @@ int rtp_relay_start_fwd (osip_call_id_t *callid, char *client_id,
|
||||
(compare_callid(callid, &cid) == STS_SUCCESS) &&
|
||||
(rtp_proxytable[i].direction == rtp_direction) &&
|
||||
(rtp_proxytable[i].media_stream_no == media_stream_no) &&
|
||||
(strcmp(rtp_proxytable[i].client_id, client_id) == 0)) {
|
||||
(compare_client_id(rtp_proxytable[i].client_id, client_id) ==
|
||||
STS_SUCCESS)) {
|
||||
/*
|
||||
* The RTP port number reported by the UA MAY change
|
||||
* for a given media stream
|
||||
@ -696,11 +686,8 @@ int rtp_relay_start_fwd (osip_call_id_t *callid, char *client_id,
|
||||
rtp_proxytable[freeidx].callid_host[0]='\0';
|
||||
}
|
||||
|
||||
if (client_id) {
|
||||
strcpy(rtp_proxytable[freeidx].client_id, client_id);
|
||||
} else {
|
||||
rtp_proxytable[freeidx].client_id[0]='\0';
|
||||
}
|
||||
/* store the passed Client-ID data */
|
||||
memcpy(&rtp_proxytable[freeidx].client_id, &client_id, sizeof(client_id_t));
|
||||
|
||||
rtp_proxytable[freeidx].direction = rtp_direction;
|
||||
rtp_proxytable[freeidx].media_stream_no = media_stream_no;
|
||||
@ -741,10 +728,10 @@ int rtp_relay_start_fwd (osip_call_id_t *callid, char *client_id,
|
||||
|
||||
//&&&
|
||||
DEBUGC(DBCLASS_RTP,"rtp_relay_start_fwd: started RTP proxy "
|
||||
"stream for: %s@%s[%s] (%s) #=%i idx=%i",
|
||||
"stream for: CallID=%s@%s [Client-ID=%s] %s #=%i idx=%i",
|
||||
rtp_proxytable[freeidx].callid_number,
|
||||
rtp_proxytable[freeidx].callid_host,
|
||||
rtp_proxytable[freeidx].client_id,
|
||||
rtp_proxytable[freeidx].client_id.contact,
|
||||
((rtp_proxytable[freeidx].direction == DIR_INCOMING) ? "incoming RTP" : "outgoing RTP"),
|
||||
rtp_proxytable[freeidx].media_stream_no, freeidx);
|
||||
|
||||
|
||||
@ -117,6 +117,18 @@ typedef struct {
|
||||
} sip_ticket_t;
|
||||
|
||||
|
||||
/*
|
||||
* Client_ID - used to identify the two sides of a Call when one
|
||||
* call is routed twice (in->out and back out->in) through siproxd
|
||||
* e.g. local UA1 is calling local UA2 via an external Registrar
|
||||
*/
|
||||
#define CLIENT_ID_SIZE 128
|
||||
typedef struct {
|
||||
char contact[CLIENT_ID_SIZE];
|
||||
struct in_addr from_ip;
|
||||
/*... maybe more to come ...*/
|
||||
} client_id_t;
|
||||
|
||||
|
||||
/*
|
||||
* Function prototypes
|
||||
@ -164,6 +176,7 @@ int get_interface_ip(int interface, struct in_addr *retaddr); /*X*/
|
||||
char *utils_inet_ntoa(struct in_addr in);
|
||||
int utils_inet_aton(const char *cp, struct in_addr *inp);
|
||||
int createpidfile(char *pidfilename); /*X*/
|
||||
int compare_client_id(client_id_t cid1, client_id_t cid2); /*X*/
|
||||
|
||||
/* sip_utils.c */
|
||||
osip_message_t * msg_make_template_reply (sip_ticket_t *ticket, int code);
|
||||
@ -189,7 +202,7 @@ int make_default_config(void); /*X*/
|
||||
|
||||
/* rtpproxy.c */
|
||||
int rtpproxy_init( void ); /*X*/
|
||||
int rtp_start_fwd (osip_call_id_t *callid, char *client_id, /*X*/
|
||||
int rtp_start_fwd (osip_call_id_t *callid, client_id_t client_id, /*X*/
|
||||
int direction, int media_stream_no,
|
||||
struct in_addr outbound_ipaddr, int *outboundport,
|
||||
struct in_addr lcl_client_ipaddr, int lcl_clientport,
|
||||
@ -246,8 +259,8 @@ int sip_message_set_body(osip_message_t * sip, const char *buf, size_t len);
|
||||
/* (assume approx one Ethernet MTU) */
|
||||
|
||||
#define URL_STRING_SIZE 128 /* max size of an URL/URI string */
|
||||
#define STATUSCODE_SIZE 5 /* size of string representation of status */
|
||||
#define DNS_CACHE_SIZE 256 /* number of entries in internal DNS cache */
|
||||
#define STATUSCODE_SIZE 5 /* size of string representation of status */
|
||||
#define DNS_CACHE_SIZE 256 /* number of entries in internal DNS cache */
|
||||
#define DNS_MAX_AGE 60 /* maximum age of an cache entry (sec) */
|
||||
#define IFADR_CACHE_SIZE 32 /* number of entries in internal IFADR cache */
|
||||
#define IFADR_MAX_AGE 5 /* max. age of the IF address cache (sec) */
|
||||
@ -255,8 +268,9 @@ int sip_message_set_body(osip_message_t * sip, const char *buf, size_t len);
|
||||
#define HOSTNAME_SIZE 128 /* max string length of a hostname */
|
||||
#define USERNAME_SIZE 128 /* max string length of a username (auth) */
|
||||
#define PASSWORD_SIZE 128 /* max string length of a password (auth) */
|
||||
#define VIA_BRANCH_SIZE 128 /* max string length for via branch param */
|
||||
#define VIA_BRANCH_SIZE 128 /* max string length for via branch param */
|
||||
/* scratch buffer for gethostbyname_r() */
|
||||
|
||||
#if defined(PR_NETDB_BUF_SIZE)
|
||||
#define GETHOSTBYNAME_BUFLEN PR_NETDB_BUF_SIZE
|
||||
#else
|
||||
|
||||
29
src/utils.c
29
src/utils.c
@ -526,3 +526,32 @@ int createpidfile(char *pidfilename) {
|
||||
return STS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
*/
|
||||
int compare_client_id(client_id_t cid1, client_id_t cid2) {
|
||||
|
||||
/* Prio 1: Contact - if present */
|
||||
if ((cid1.contact[0] != '\0') && (cid2.contact[0] != '\0')) {
|
||||
if (strcmp(cid1.contact, cid2.contact) == 0) {
|
||||
DEBUGC(DBCLASS_BABBLE, "compare_client_id: contact match [%s]",
|
||||
cid1.contact);
|
||||
return STS_SUCCESS;
|
||||
}
|
||||
DEBUGC(DBCLASS_BABBLE, "compare_client_id: contact NO match [%s<->%s]",
|
||||
cid1.contact, cid2.contact);
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
/* Prio 2: IP (always present) */
|
||||
if (memcmp(&cid1.from_ip, &cid2.from_ip, sizeof(struct in_addr)) == 0) {
|
||||
DEBUGC(DBCLASS_BABBLE, "compare_client_id: IP match [%s]",
|
||||
utils_inet_ntoa(cid1.from_ip));
|
||||
return STS_SUCCESS;
|
||||
}
|
||||
|
||||
DEBUGC(DBCLASS_BABBLE, "compare_client_id: no match");
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user