- 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:
Thomas Ries 2007-05-29 20:08:29 +00:00
parent f303dd3b5d
commit f6b0b49bf9
7 changed files with 96 additions and 52 deletions

View File

@ -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

View File

@ -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'

View File

@ -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,

View File

@ -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,

View File

@ -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);

View File

@ -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

View File

@ -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;
}