- full duplex RTP proxy (many thanks to Chris Ross for
his work on this). Up to now, only the RTP *Relay* has been tested (works with KPhone, BudgeTone) - fix: SIP phones that allocate a random port for incomming SIP traffic should now work (like BudgeTone) - fix: some SIP phones do change the RTP port number during a session (like KPhone during HOLD/unHOLD)
This commit is contained in:
@@ -1,5 +1,12 @@
|
||||
0.5.1
|
||||
=====
|
||||
17-Dec-2003: - full duplex RTP proxy (many thanks to Chris Ross for
|
||||
his work on this). Up to now, only the RTP *Relay*
|
||||
has been tested (works with KPhone, BudgeTone)
|
||||
- fix: SIP phones that allocate a random port for
|
||||
incomming SIP traffic should now work (like BudgeTone)
|
||||
- fix: some SIP phones do change the RTP port number
|
||||
during a session (like KPhone during HOLD/unHOLD)
|
||||
15-Dec-2003: - use even port numbers for RTP traffic
|
||||
05-Dec-2003: - some changes & enhancements inspired by Chris Ross:
|
||||
* 183 Trying *may* contain SDP data
|
||||
|
||||
+78
-24
@@ -167,12 +167,22 @@ INFO("stopping RTP proxy stream for: %s@%s",
|
||||
osip_message_get_call_id(request)->number,
|
||||
osip_message_get_call_id(request)->host);
|
||||
#endif
|
||||
/* stop the RTP proxying stream */
|
||||
rtp_stop_fwd(osip_message_get_call_id(request));
|
||||
/* stop the RTP proxying stream(s) */
|
||||
rtp_stop_fwd(osip_message_get_call_id(request), incoming);
|
||||
rtp_stop_fwd(osip_message_get_call_id(request), outgoing);
|
||||
|
||||
/* check for incomming request */
|
||||
/* check for incoming request */
|
||||
} else if (MSG_IS_INVITE(request)) {
|
||||
osip_uri_t *contact;
|
||||
|
||||
/* First, rewrite the body */
|
||||
sts = proxy_rewrite_invitation_body(request, incoming);
|
||||
|
||||
/*
|
||||
* Note: Incoming request has no need to rewrite Contact
|
||||
* header as we are not masquerading something there
|
||||
*/
|
||||
|
||||
contact=((osip_contact_t*)(request->contacts->node->element))->url;
|
||||
if (contact) {
|
||||
INFO("Incomming Call from: %s:%s",
|
||||
@@ -219,7 +229,7 @@ INFO("stopping RTP proxy stream for: %s@%s",
|
||||
|
||||
/* if an INVITE, rewrite body */
|
||||
if (MSG_IS_INVITE(request)) {
|
||||
sts = proxy_rewrite_invitation_body(request);
|
||||
sts = proxy_rewrite_invitation_body(request, outgoing);
|
||||
}
|
||||
|
||||
/* rewrite Contact header to represent the masqued address */
|
||||
@@ -259,7 +269,8 @@ INFO("stopping RTP proxy stream for: %s@%s",
|
||||
|
||||
/* if this is CANCEL/BYE request, stop RTP proxying */
|
||||
if (MSG_IS_BYE(request) || MSG_IS_CANCEL(request)) {
|
||||
rtp_stop_fwd(osip_message_get_call_id(request));
|
||||
rtp_stop_fwd(osip_message_get_call_id(request), incoming);
|
||||
rtp_stop_fwd(osip_message_get_call_id(request), outgoing);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -410,6 +421,17 @@ int proxy_response (osip_message_t *response) {
|
||||
* from an external host to the internal masqueraded host
|
||||
*/
|
||||
case RESTYP_INCOMING:
|
||||
if ((MSG_IS_RESPONSE_FOR(response,"INVITE")) &&
|
||||
((MSG_TEST_CODE(response, 200)) ||
|
||||
(MSG_TEST_CODE(response, 183)))) {
|
||||
/* This is an incoming response, therefore we need an incoming stream */
|
||||
sts = proxy_rewrite_invitation_body(response, incoming);
|
||||
|
||||
/*
|
||||
* Note: Incoming request has no need to rewrite Contact
|
||||
* header as we are not masquerading something there
|
||||
*/
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
@@ -422,7 +444,8 @@ int proxy_response (osip_message_t *response) {
|
||||
if ((MSG_IS_RESPONSE_FOR(response,"INVITE")) &&
|
||||
((MSG_TEST_CODE(response, 200)) ||
|
||||
(MSG_TEST_CODE(response, 183)))) {
|
||||
sts = proxy_rewrite_invitation_body(response);
|
||||
/* This is an outgoing response, therefore an outgoing stream */
|
||||
sts = proxy_rewrite_invitation_body(response, outgoing);
|
||||
}
|
||||
|
||||
/* rewrite Contact header to represent the masqued address */
|
||||
@@ -518,14 +541,14 @@ int proxy_response (osip_message_t *response) {
|
||||
* STS_SUCCESS on success
|
||||
* STS_FAILURE on error
|
||||
*/
|
||||
int proxy_rewrite_invitation_body(osip_message_t *mymsg){
|
||||
int proxy_rewrite_invitation_body(osip_message_t *mymsg, rtp_direction dir){
|
||||
osip_body_t *body;
|
||||
sdp_message_t *sdp;
|
||||
struct in_addr outb_addr, lcl_clnt_addr;
|
||||
struct in_addr map_addr, msg_addr, outside_addr, inside_addr;
|
||||
int sts;
|
||||
char *bodybuff;
|
||||
char clen[8]; /* content length: probably never more than 7 digits !*/
|
||||
int outb_rtp_port, inb_clnt_port;
|
||||
int map_port, msg_port;
|
||||
int media_stream_no;
|
||||
sdp_connection_t *sdp_conn;
|
||||
sdp_media_t *sdp_med;
|
||||
@@ -552,7 +575,7 @@ int proxy_rewrite_invitation_body(osip_message_t *mymsg){
|
||||
sts = sdp_message_parse (sdp, bodybuff);
|
||||
osip_free(bodybuff);
|
||||
if (sts != 0) {
|
||||
ERROR("rewrite_invitation_body: unable to sdp_parse body");
|
||||
ERROR("rewrite_invitation_body: unable to sdp_message_parse body");
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
@@ -573,28 +596,54 @@ if (configuration.debuglevel)
|
||||
* RTP proxy: get ready and start forwarding
|
||||
* start forwarding for each media stream ('m=' item in SIP message)
|
||||
*/
|
||||
sts = get_ip_by_host(sdp_message_c_addr_get(sdp,-1,0), &lcl_clnt_addr);
|
||||
sts = get_ip_by_host(sdp_message_c_addr_get(sdp,-1,0), &msg_addr);
|
||||
if (sts == STS_FAILURE) {
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: cannot resolve "
|
||||
"m= (media) host [%s]", sdp_message_c_addr_get(sdp,-1,0));
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
sts = get_ip_by_ifname(configuration.outbound_if, &outb_addr);
|
||||
sts = get_ip_by_ifname(configuration.outbound_if, &outside_addr);
|
||||
if (sts == STS_FAILURE) {
|
||||
ERROR("can't find outbound interface %s - configuration error?",
|
||||
configuration.inbound_if);
|
||||
configuration.outbound_if);
|
||||
return STS_FAILURE;
|
||||
}
|
||||
sts = get_ip_by_ifname(configuration.inbound_if, &inside_addr);
|
||||
if (sts == STS_FAILURE) {
|
||||
ERROR("can't find inbound interface %s - configuration error?",
|
||||
configuration.inbound_if);
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
/* figure out what address to use for RTP masquerading */
|
||||
if (MSG_IS_REQUEST(mymsg)) {
|
||||
if (dir == incoming)
|
||||
map_addr = inside_addr;
|
||||
else
|
||||
map_addr = outside_addr;
|
||||
} else /* MSG_IS_REPONSE(mymsg) */ {
|
||||
if (dir == incoming)
|
||||
map_addr = inside_addr;
|
||||
else
|
||||
map_addr = outside_addr;
|
||||
}
|
||||
|
||||
/*
|
||||
* rewrite c= address
|
||||
* !! an IP address of 0.0.0.0 means *MUTE*, don't rewrite such one
|
||||
*/
|
||||
sdp_conn = sdp_message_connection_get (sdp, -1, 0);
|
||||
if (sdp_conn && sdp_conn->c_addr) {
|
||||
osip_free(sdp_conn->c_addr);
|
||||
sdp_conn->c_addr=osip_malloc(HOSTNAME_SIZE);
|
||||
sprintf(sdp_conn->c_addr, "%s", utils_inet_ntoa(outb_addr));
|
||||
if (strcmp(sdp_conn->c_addr, "0.0.0.0") != 0) {
|
||||
/* have a valid address */
|
||||
osip_free(sdp_conn->c_addr);
|
||||
sdp_conn->c_addr=osip_malloc(HOSTNAME_SIZE);
|
||||
sprintf(sdp_conn->c_addr, "%s", utils_inet_ntoa(map_addr));
|
||||
} else {
|
||||
/* 0.0.0.0 - don't rewrite */
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: got a MUTE c= record");
|
||||
}
|
||||
} else {
|
||||
ERROR("got NULL c= address record - can't rewrite");
|
||||
}
|
||||
@@ -609,20 +658,20 @@ if (configuration.debuglevel)
|
||||
|
||||
/* start an RTP proxying stream */
|
||||
if (sdp_message_m_port_get(sdp, media_stream_no)) {
|
||||
inb_clnt_port=atoi(sdp_message_m_port_get(sdp, media_stream_no));
|
||||
msg_port=atoi(sdp_message_m_port_get(sdp, media_stream_no));
|
||||
|
||||
if (inb_clnt_port > 0) {
|
||||
rtp_start_fwd(osip_message_get_call_id(mymsg), media_stream_no,
|
||||
outb_addr, &outb_rtp_port,
|
||||
lcl_clnt_addr, inb_clnt_port);
|
||||
if (msg_port > 0) {
|
||||
rtp_start_fwd(osip_message_get_call_id(mymsg), dir, media_stream_no,
|
||||
map_addr, &map_port,
|
||||
msg_addr, msg_port);
|
||||
/* and rewrite the port */
|
||||
sdp_med=osip_list_get(sdp->m_medias, media_stream_no);
|
||||
if (sdp_med && sdp_med->m_port) {
|
||||
osip_free(sdp_med->m_port);
|
||||
sdp_med->m_port=osip_malloc(8);
|
||||
sprintf(sdp_med->m_port, "%i", outb_rtp_port);
|
||||
sprintf(sdp_med->m_port, "%i", map_port);
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: "
|
||||
"m= rewrote port to [%i]",outb_rtp_port);
|
||||
"m= rewrote port to [%i]",map_port);
|
||||
|
||||
} else {
|
||||
ERROR("rewriting port in m= failed sdp_med=%p, "
|
||||
@@ -686,10 +735,12 @@ int proxy_rewrite_request_uri(osip_message_t *mymsg, int idx){
|
||||
|
||||
DEBUGC(DBCLASS_PROXY,"rewriting incoming Request URI");
|
||||
url=osip_message_get_uri(mymsg);
|
||||
osip_free(url->host);url->host=NULL;
|
||||
|
||||
/* set the true host */
|
||||
if(urlmap[idx].true_url->host) {
|
||||
osip_free(url->host);url->host=NULL;
|
||||
DEBUGC(DBCLASS_BABBLE,"proxy_rewrite_request_uri: host=%s",
|
||||
urlmap[idx].true_url->host);
|
||||
host = (char *)malloc(strlen(urlmap[idx].true_url->host)+1);
|
||||
memcpy(host, urlmap[idx].true_url->host, strlen(urlmap[idx].true_url->host));
|
||||
host[strlen(urlmap[idx].true_url->host)]='\0';
|
||||
@@ -698,6 +749,9 @@ int proxy_rewrite_request_uri(osip_message_t *mymsg, int idx){
|
||||
|
||||
/* set the true port */
|
||||
if(urlmap[idx].true_url->port) {
|
||||
osip_free(url->port);url->port=NULL;
|
||||
DEBUGC(DBCLASS_BABBLE,"proxy_rewrite_request_uri: port=%s",
|
||||
urlmap[idx].true_url->port);
|
||||
port = (char *)malloc(strlen(urlmap[idx].true_url->port)+1);
|
||||
memcpy(port, urlmap[idx].true_url->port, strlen(urlmap[idx].true_url->port));
|
||||
port[strlen(urlmap[idx].true_url->port)]='\0';
|
||||
|
||||
+19
-4
@@ -252,10 +252,12 @@ int register_client(osip_message_t *my_msg, int force_lcl_masq) {
|
||||
|
||||
/* write entry */
|
||||
urlmap[i].active=1;
|
||||
/* Contact: field */
|
||||
osip_uri_clone( ((osip_contact_t*)(my_msg->contacts->node->element))->url,
|
||||
&urlmap[i].true_url); /* Contact: field */
|
||||
&urlmap[i].true_url);
|
||||
/* To: field */
|
||||
osip_uri_clone( my_msg->to->url,
|
||||
&urlmap[i].reg_url); /* To: field */
|
||||
&urlmap[i].reg_url);
|
||||
|
||||
DEBUGC(DBCLASS_REG,"create new entry for %s@%s <-> %s@%s at slot=%i",
|
||||
(url1_contact->username) ? url1_contact->username : "*NULL*",
|
||||
@@ -318,8 +320,21 @@ int register_client(osip_message_t *my_msg, int force_lcl_masq) {
|
||||
/* remember the VIA for later use */
|
||||
// osip_via_clone( ((osip_via_t*)(my_msg->vias->node->element)),
|
||||
// &urlmap[i].via);
|
||||
} /* if new entry */
|
||||
|
||||
} else { /* if new entry */
|
||||
/*
|
||||
* Some phones (like BudgeTones *may* dynamically grab a SIP port
|
||||
* so we might want to update the true_url and reg_url each time
|
||||
* we get an REGISTER
|
||||
*/
|
||||
/* Contact: field */
|
||||
osip_uri_free(urlmap[i].true_url);
|
||||
osip_uri_clone( ((osip_contact_t*)(my_msg->contacts->node->element))->url,
|
||||
&urlmap[i].true_url);
|
||||
/* To: field */
|
||||
osip_uri_free(urlmap[i].reg_url);
|
||||
osip_uri_clone( my_msg->to->url,
|
||||
&urlmap[i].reg_url);
|
||||
}
|
||||
/* give some safety margin for the next update */
|
||||
if (expires > 0) expires+=30;
|
||||
|
||||
|
||||
+9
-8
@@ -68,7 +68,8 @@ int rtpproxy_init( void ) {
|
||||
* STS_SUCCESS on success
|
||||
* STS_FAILURE on error
|
||||
*/
|
||||
int rtp_start_fwd (osip_call_id_t *callid, int media_stream_no,
|
||||
int rtp_start_fwd (osip_call_id_t *callid, rtp_direction dir,
|
||||
int media_stream_no,
|
||||
struct in_addr outbound_ipaddr, int *outboundport,
|
||||
struct in_addr lcl_client_ipaddr, int lcl_clientport) {
|
||||
int sts=STS_FAILURE;
|
||||
@@ -76,15 +77,15 @@ int rtp_start_fwd (osip_call_id_t *callid, int media_stream_no,
|
||||
if (configuration.rtp_proxy_enable == 0) {
|
||||
sts = STS_SUCCESS;
|
||||
} else if (configuration.rtp_proxy_enable == 1) { // Relay
|
||||
sts = rtp_relay_start_fwd (callid, media_stream_no,
|
||||
sts = rtp_relay_start_fwd (callid, dir, media_stream_no,
|
||||
outbound_ipaddr, outboundport,
|
||||
lcl_client_ipaddr, lcl_clientport);
|
||||
} else if (configuration.rtp_proxy_enable == 2) { // MASQ tunnels (ipchains)
|
||||
sts = rtp_masq_start_fwd (callid, media_stream_no,
|
||||
sts = rtp_masq_start_fwd (callid, dir, media_stream_no,
|
||||
outbound_ipaddr, outboundport,
|
||||
lcl_client_ipaddr, lcl_clientport);
|
||||
} else if (configuration.rtp_proxy_enable == 3) { // MASQ tunnels (netfilter)
|
||||
sts = rtp_masq_start_fwd (callid, media_stream_no,
|
||||
sts = rtp_masq_start_fwd (callid, dir, media_stream_no,
|
||||
outbound_ipaddr, outboundport,
|
||||
lcl_client_ipaddr, lcl_clientport);
|
||||
} else {
|
||||
@@ -103,17 +104,17 @@ int rtp_start_fwd (osip_call_id_t *callid, int media_stream_no,
|
||||
* STS_SUCCESS on success
|
||||
* STS_FAILURE on error
|
||||
*/
|
||||
int rtp_stop_fwd (osip_call_id_t *callid) {
|
||||
int rtp_stop_fwd (osip_call_id_t *callid, rtp_direction dir) {
|
||||
int sts = STS_FAILURE;
|
||||
|
||||
if (configuration.rtp_proxy_enable == 0) {
|
||||
sts = STS_SUCCESS;
|
||||
} else if (configuration.rtp_proxy_enable == 1) { // Relay
|
||||
sts = rtp_relay_stop_fwd(callid, 0);
|
||||
sts = rtp_relay_stop_fwd(callid, dir, 0);
|
||||
} else if (configuration.rtp_proxy_enable == 2) { // MASQ tunnels (ipchains)
|
||||
sts = rtp_masq_stop_fwd(callid);
|
||||
sts = rtp_masq_stop_fwd(callid, dir);
|
||||
} else if (configuration.rtp_proxy_enable == 3) { // MASQ tunnels (netfilter)
|
||||
sts = rtp_masq_stop_fwd(callid);
|
||||
sts = rtp_masq_stop_fwd(callid, dir);
|
||||
} else {
|
||||
ERROR("CONFIG: rtp_proxy_enable has invalid value",
|
||||
configuration.rtp_proxy_enable);
|
||||
|
||||
+7
-4
@@ -25,6 +25,7 @@ typedef struct {
|
||||
int sock;
|
||||
char callid_number[CALLIDNUM_SIZE]; /* call ID */
|
||||
char callid_host[CALLIDHOST_SIZE]; /* --"-- */
|
||||
rtp_direction direction; /* Direction of RTP stream */
|
||||
int media_stream_no;
|
||||
struct in_addr outbound_ipaddr; /* lcl outbound IP */
|
||||
int outboundport; /* lcl allocd outbound port */
|
||||
@@ -37,20 +38,22 @@ typedef struct {
|
||||
* RTP relay
|
||||
*/
|
||||
int rtp_relay_init(void);
|
||||
int rtp_relay_start_fwd (osip_call_id_t *callid, int media_stream_no,
|
||||
int rtp_relay_start_fwd (osip_call_id_t *callid, rtp_direction dir,
|
||||
int media_stream_no,
|
||||
struct in_addr outbound_ipaddr, int *outboundport,
|
||||
struct in_addr lcl_client_ipaddr, int lcl_clientport);
|
||||
int rtp_relay_stop_fwd (osip_call_id_t *callid, int nolock);
|
||||
int rtp_relay_stop_fwd (osip_call_id_t *callid, rtp_direction dir, int nolock);
|
||||
|
||||
|
||||
/*
|
||||
* RTP masquerading
|
||||
*/
|
||||
int rtp_masq_init(void);
|
||||
int rtp_masq_start_fwd (osip_call_id_t *callid, int media_stream_no,
|
||||
int rtp_masq_start_fwd (osip_call_id_t *callid, rtp_direction dir,
|
||||
int media_stream_no,
|
||||
struct in_addr outbound_ipaddr, int *outboundport,
|
||||
struct in_addr lcl_client_ipaddr, int lcl_clientport);
|
||||
int rtp_masq_stop_fwd (osip_call_id_t *callid);
|
||||
int rtp_masq_stop_fwd (osip_call_id_t *callid, rtp_direction dir);
|
||||
|
||||
/*
|
||||
* RTP masquerading (ipchains part)
|
||||
|
||||
+28
-17
@@ -85,7 +85,8 @@ int rtp_masq_init( void ) {
|
||||
}
|
||||
|
||||
|
||||
int rtp_masq_start_fwd(osip_call_id_t *callid, int media_stream_no,
|
||||
int rtp_masq_start_fwd(osip_call_id_t *callid, rtp_direction dir,
|
||||
int media_stream_no,
|
||||
struct in_addr outbound_ipaddr, int *outbound_lcl_port,
|
||||
struct in_addr lcl_client_ipaddr, int lcl_clientport) {
|
||||
int sts=STS_FAILURE;
|
||||
@@ -95,7 +96,7 @@ int rtp_masq_start_fwd(osip_call_id_t *callid, int media_stream_no,
|
||||
osip_call_id_t cid;
|
||||
|
||||
if (callid == NULL) {
|
||||
ERROR("rtp_relay_start_fwd: callid is NULL!");
|
||||
ERROR("rtp_masq_start_fwd: callid is NULL!");
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
@@ -107,13 +108,13 @@ int rtp_masq_start_fwd(osip_call_id_t *callid, int media_stream_no,
|
||||
* the constants CALLIDNUM_SIZE and/or CALLIDHOST_SIZE.
|
||||
*/
|
||||
if (callid->number && strlen(callid->number) > CALLIDNUM_SIZE) {
|
||||
ERROR("rtp_relay_start_fwd: received callid number "
|
||||
ERROR("rtp_masq_start_fwd: received callid number "
|
||||
"has too many characters (%i, max=%i)",
|
||||
strlen(callid->number),CALLIDNUM_SIZE);
|
||||
return STS_FAILURE;
|
||||
}
|
||||
if (callid->host && strlen(callid->host) > CALLIDHOST_SIZE) {
|
||||
ERROR("rtp_relay_start_fwd: received callid host "
|
||||
ERROR("rtp_masq_start_fwd: received callid host "
|
||||
"has too many characters (%i, max=%i)",
|
||||
strlen(callid->host),CALLIDHOST_SIZE);
|
||||
return STS_FAILURE;
|
||||
@@ -149,7 +150,7 @@ int rtp_masq_start_fwd(osip_call_id_t *callid, int media_stream_no,
|
||||
/* this one has expired, delete it */
|
||||
cid.number = rtp_proxytable[i].callid_number;
|
||||
cid.host = rtp_proxytable[i].callid_host;
|
||||
rtp_masq_stop_fwd(&cid);
|
||||
rtp_masq_stop_fwd(&cid, rtp_proxytable[i].direction);
|
||||
DEBUGC(DBCLASS_RTP,"deleting expired proxy slot #%i %s@%s", i,
|
||||
rtp_proxytable[i].callid_number,
|
||||
rtp_proxytable[i].callid_host);
|
||||
@@ -157,15 +158,14 @@ int rtp_masq_start_fwd(osip_call_id_t *callid, int media_stream_no,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEBUGC(DBCLASS_RTP,"rtp_masq_start_fwd: starting RTP proxy "
|
||||
"stream for: %s@%s #=%i",
|
||||
callid->number, callid->host, media_stream_no);
|
||||
"stream for: %s@%s (%s) #=%i",
|
||||
callid->number, callid->host,
|
||||
((dir == incoming) ? "incoming" : "outgoing"), media_stream_no);
|
||||
|
||||
/*
|
||||
* figure out, if this is an request to start an RTP proxy stream
|
||||
* that is already existing (identified by SIP Call-ID and
|
||||
* that is already existing (identified by SIP Call-ID, direction and
|
||||
* media_stream_no). This can be due to UDP repetitions of the
|
||||
* INVITE request...
|
||||
*/
|
||||
@@ -175,6 +175,7 @@ int rtp_masq_start_fwd(osip_call_id_t *callid, int media_stream_no,
|
||||
cid.host = rtp_proxytable[i].callid_host;
|
||||
if (rtp_proxytable[i].sock != 0) {
|
||||
if((compare_callid(callid, &cid) == STS_SUCCESS) &&
|
||||
(rtp_proxytable[i].direction == dir) &&
|
||||
(rtp_proxytable[i].media_stream_no == media_stream_no)) {
|
||||
/* return the already known port number */
|
||||
*outbound_lcl_port=rtp_proxytable[i].outboundport;
|
||||
@@ -250,6 +251,7 @@ int rtp_masq_start_fwd(osip_call_id_t *callid, int media_stream_no,
|
||||
rtp_proxytable[freeidx].callid_host[0]='\0';
|
||||
}
|
||||
|
||||
rtp_proxytable[freeidx].direction = dir;
|
||||
rtp_proxytable[freeidx].media_stream_no = media_stream_no;
|
||||
memcpy(&rtp_proxytable[freeidx].outbound_ipaddr,
|
||||
&outbound_ipaddr, sizeof(struct in_addr));
|
||||
@@ -266,7 +268,7 @@ int rtp_masq_start_fwd(osip_call_id_t *callid, int media_stream_no,
|
||||
}
|
||||
|
||||
|
||||
int rtp_masq_stop_fwd(osip_call_id_t *callid) {
|
||||
int rtp_masq_stop_fwd (osip_call_id_t *callid, rtp_direction dir) {
|
||||
int sts=STS_FAILURE;
|
||||
int i;
|
||||
int got_match=0;
|
||||
@@ -275,16 +277,22 @@ int rtp_masq_stop_fwd(osip_call_id_t *callid) {
|
||||
/* let the UDP tunnel time-out */
|
||||
|
||||
if (callid == NULL) {
|
||||
ERROR("rtp_relay_stop_fwd: callid is NULL!");
|
||||
ERROR("rtp_masq_stop_fwd: callid is NULL!");
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
DEBUGC(DBCLASS_RTP,"rtp_masq_stop_fwd: stopping RTP proxy "
|
||||
"stream for: %s@%s (%s)",
|
||||
callid->number, callid->host,
|
||||
((dir == incoming) ? "incoming" : "outgoing"));
|
||||
|
||||
for (i=0; i<RTPPROXY_SIZE; i++) {
|
||||
cid.number = rtp_proxytable[i].callid_number;
|
||||
cid.host = rtp_proxytable[i].callid_host;
|
||||
|
||||
if (rtp_proxytable[i].sock &&
|
||||
(compare_callid(callid, &cid) == STS_SUCCESS)) {
|
||||
(compare_callid(callid, &cid) == STS_SUCCESS) &&
|
||||
(rtp_proxytable[i].direction == dir)) {
|
||||
|
||||
/* remove masquerading entry */
|
||||
if (configuration.rtp_proxy_enable == 2) { // ipchains
|
||||
@@ -314,8 +322,10 @@ int rtp_masq_stop_fwd(osip_call_id_t *callid) {
|
||||
|
||||
/* did not find an active stream... */
|
||||
if (!got_match) {
|
||||
DEBUGC(DBCLASS_RTP,"rtp_masq_stop_fwd: can't find active stream for %s@%s",
|
||||
callid->number, callid->host);
|
||||
DEBUGC(DBCLASS_RTP,
|
||||
"rtp_masq_stop_fwd: can't find active stream for %s@%s (%s)",
|
||||
callid->number, callid->host,
|
||||
((dir == incoming) ? "incoming" : "outgoing"));
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
@@ -332,13 +342,14 @@ int rtp_masq_init( void ) {
|
||||
ERROR("Masquerading support is not enabled (compile time config option)");
|
||||
return STS_FAILURE;
|
||||
}
|
||||
int rtp_masq_start_fwd(osip_call_id_t *callid, int media_stream_no,
|
||||
int rtp_masq_start_fwd(osip_call_id_t *callid, rtp_direction dir,
|
||||
int media_stream_no,
|
||||
struct in_addr outbound_ipaddr, int *outbound_lcl_port,
|
||||
struct in_addr lcl_client_ipaddr, int lcl_clientport) {
|
||||
outbound_lcl_port=0;
|
||||
return STS_FAILURE;
|
||||
}
|
||||
int rtp_masq_stop_fwd(osip_call_id_t *callid) {
|
||||
int rtp_masq_stop_fwd (osip_call_id_t *callid, rtp_direction dir) {
|
||||
return STS_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
+35
-14
@@ -201,8 +201,8 @@ if (sts != STS_SUCCESS) {WARN("sipsock_send_udp() returned error");}
|
||||
DEBUGC(DBCLASS_RTP,"RTP stream sock=%i %s@%s (idx=%i) "
|
||||
"has expired", rtp_proxytable[i].sock,
|
||||
callid.number, callid.host, i);
|
||||
rtp_relay_stop_fwd(&callid, 1); /* don't lock the mutex, as we own
|
||||
the lock already here */
|
||||
/* don't lock the mutex, as we own the lock already here */
|
||||
rtp_relay_stop_fwd(&callid, rtp_proxytable[i].direction, 1);
|
||||
}
|
||||
}
|
||||
} /* if (t>...) */
|
||||
@@ -228,9 +228,10 @@ if (sts != STS_SUCCESS) {WARN("sipsock_send_udp() returned error");}
|
||||
* STS_SUCCESS on success
|
||||
* STS_FAILURE on error
|
||||
*/
|
||||
int rtp_relay_start_fwd (osip_call_id_t *callid, int media_stream_no,
|
||||
struct in_addr outbound_ipaddr, int *outboundport,
|
||||
struct in_addr lcl_client_ipaddr, int lcl_clientport) {
|
||||
int rtp_relay_start_fwd (osip_call_id_t *callid, rtp_direction dir,
|
||||
int media_stream_no, struct in_addr outbound_ipaddr,
|
||||
int *outboundport, struct in_addr lcl_client_ipaddr,
|
||||
int lcl_clientport) {
|
||||
int i, j;
|
||||
int sock, port;
|
||||
int freeidx;
|
||||
@@ -262,8 +263,10 @@ int rtp_relay_start_fwd (osip_call_id_t *callid, int media_stream_no,
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
DEBUGC(DBCLASS_RTP,"starting RTP proxy stream for: %s@%s #=%i",
|
||||
callid->number, callid->host, media_stream_no);
|
||||
DEBUGC(DBCLASS_RTP,"rtp_relay_start_fwd: starting RTP proxy "
|
||||
"stream for: %s@%s (%s) #=%i",
|
||||
callid->number, callid->host,
|
||||
((dir == incoming) ? "incoming" : "outgoing"), media_stream_no);
|
||||
|
||||
/* lock mutex */
|
||||
#define return is_forbidden_in_this_code_section
|
||||
@@ -279,7 +282,7 @@ int rtp_relay_start_fwd (osip_call_id_t *callid, int media_stream_no,
|
||||
|
||||
/*
|
||||
* figure out, if this is an request to start an RTP proxy stream
|
||||
* that is already existing (identified by SIP Call-ID and
|
||||
* that is already existing (identified by SIP Call-ID, direction and
|
||||
* media_stream_no). This can be due to UDP repetitions of the
|
||||
* INVITE request...
|
||||
*/
|
||||
@@ -288,7 +291,18 @@ int rtp_relay_start_fwd (osip_call_id_t *callid, int media_stream_no,
|
||||
cid.host = rtp_proxytable[i].callid_host;
|
||||
if (rtp_proxytable[i].sock &&
|
||||
(compare_callid(callid, &cid) == STS_SUCCESS) &&
|
||||
(rtp_proxytable[i].direction == dir) &&
|
||||
(rtp_proxytable[i].media_stream_no == media_stream_no) ) {
|
||||
/*
|
||||
* The RTP port number reported by the UA MAY change
|
||||
* for a given media stream
|
||||
* (seen with KPhone during HOLD/unHOLD)
|
||||
*/
|
||||
if (rtp_proxytable[i].inbound_client_port != lcl_clientport) {
|
||||
DEBUGC(DBCLASS_RTP,"RTP port number changed %i -> %i",
|
||||
rtp_proxytable[i].inbound_client_port, lcl_clientport);
|
||||
rtp_proxytable[i].inbound_client_port = lcl_clientport;
|
||||
}
|
||||
/* return the already known port number */
|
||||
DEBUGC(DBCLASS_RTP,"RTP stream already active (port=%i, "
|
||||
"id=%s, #=%i)", rtp_proxytable[i].outboundport,
|
||||
@@ -369,6 +383,7 @@ int rtp_relay_start_fwd (osip_call_id_t *callid, int media_stream_no,
|
||||
rtp_proxytable[freeidx].callid_host[0]='\0';
|
||||
}
|
||||
|
||||
rtp_proxytable[freeidx].direction = dir;
|
||||
rtp_proxytable[freeidx].media_stream_no = media_stream_no;
|
||||
memcpy(&rtp_proxytable[freeidx].outbound_ipaddr,
|
||||
&outbound_ipaddr, sizeof(struct in_addr));
|
||||
@@ -403,7 +418,8 @@ unlock_and_exit:
|
||||
* STS_SUCCESS on success
|
||||
* STS_FAILURE on error
|
||||
*/
|
||||
int rtp_relay_stop_fwd (osip_call_id_t *callid, int nolock) {
|
||||
int rtp_relay_stop_fwd (osip_call_id_t *callid, rtp_direction dir,
|
||||
int nolock) {
|
||||
int i, sts;
|
||||
int retsts=STS_SUCCESS;
|
||||
int got_match=0;
|
||||
@@ -414,8 +430,10 @@ int rtp_relay_stop_fwd (osip_call_id_t *callid, int nolock) {
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
DEBUGC(DBCLASS_RTP,"stopping RTP proxy stream for: %s@%s",
|
||||
callid->number, callid->host);
|
||||
DEBUGC(DBCLASS_RTP,"rtp_relay_stop_fwd: stopping RTP proxy "
|
||||
"stream for: %s@%s (%s)",
|
||||
callid->number, callid->host,
|
||||
((dir == incoming) ? "incoming" : "outgoing"));
|
||||
|
||||
/*
|
||||
* lock mutex - only if not requested to skip the lock.
|
||||
@@ -452,7 +470,8 @@ int rtp_relay_stop_fwd (osip_call_id_t *callid, int nolock) {
|
||||
cid.number = rtp_proxytable[i].callid_number;
|
||||
cid.host = rtp_proxytable[i].callid_host;
|
||||
if (rtp_proxytable[i].sock &&
|
||||
(compare_callid(callid, &cid) == STS_SUCCESS)) {
|
||||
(compare_callid(callid, &cid) == STS_SUCCESS) &&
|
||||
(rtp_proxytable[i].direction == dir)) {
|
||||
sts = close(rtp_proxytable[i].sock);
|
||||
DEBUGC(DBCLASS_RTP,"closed socket %i for RTP stream "
|
||||
"%s:%s == %s:%s (idx=%i) sts=%i",
|
||||
@@ -474,8 +493,10 @@ int rtp_relay_stop_fwd (osip_call_id_t *callid, int nolock) {
|
||||
|
||||
/* did not find an active stream... */
|
||||
if (!got_match) {
|
||||
DEBUGC(DBCLASS_RTP,"rtp_relay_stop_fwd: can't find active stream for %s@%s",
|
||||
callid->number, callid->host);
|
||||
DEBUGC(DBCLASS_RTP,
|
||||
"rtp_relay_stop_fwd: can't find active stream for %s@%s (%s)",
|
||||
callid->number, callid->host,
|
||||
((dir == incoming) ? "incoming" : "outgoing"));
|
||||
retsts = STS_FAILURE;
|
||||
goto unlock_and_exit;
|
||||
}
|
||||
|
||||
+10
-3
@@ -22,6 +22,12 @@
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
|
||||
/* typedef for specifying the direction of an RTP stream [being proxied] */
|
||||
typedef enum {
|
||||
incoming,
|
||||
outgoing,
|
||||
} rtp_direction;
|
||||
|
||||
/* function returns STS_* status values vvv */
|
||||
|
||||
/* sock.c */
|
||||
@@ -42,7 +48,7 @@ int register_response(osip_message_t *request, int flag); /*X*/
|
||||
/* proxy.c */
|
||||
int proxy_request (osip_message_t *request); /*X*/
|
||||
int proxy_response (osip_message_t *response); /*X*/
|
||||
int proxy_rewrite_invitation_body(osip_message_t *mymsg); /*X*/
|
||||
int proxy_rewrite_invitation_body(osip_message_t *m, rtp_direction d); /*X*/
|
||||
int proxy_rewrite_request_uri(osip_message_t *mymsg, int idx); /*X*/
|
||||
|
||||
/* utils.c */
|
||||
@@ -71,10 +77,11 @@ int read_config(char *name, int search); /*X*/
|
||||
|
||||
/* rtpproxy.c */
|
||||
int rtpproxy_init( void ); /*X*/
|
||||
int rtp_start_fwd (osip_call_id_t *callid, int media_stream_no, /*X*/
|
||||
int rtp_start_fwd (osip_call_id_t *callid, rtp_direction dir, /*X*/
|
||||
int media_stream_no,
|
||||
struct in_addr outbound_ipaddr, int *outboundport,
|
||||
struct in_addr lcl_client_ipaddr, int lcl_clientport);
|
||||
int rtp_stop_fwd (osip_call_id_t *callid); /*X*/
|
||||
int rtp_stop_fwd (osip_call_id_t *callid, rtp_direction dir); /*X*/
|
||||
void rtpproxy_kill( void ); /*X*/
|
||||
|
||||
/* accessctl.c */
|
||||
|
||||
+4
-3
@@ -155,11 +155,12 @@ int sipsock_send_udp(int *sock, struct in_addr addr, int port,
|
||||
|
||||
if (sts == -1) {
|
||||
if (errno != ECONNREFUSED) {
|
||||
ERROR("sendto() [%s] call failed: %s", utils_inet_ntoa(addr),
|
||||
strerror(errno));
|
||||
ERROR("sendto() [%s:%i] call failed: %s", utils_inet_ntoa(addr),
|
||||
port, strerror(errno));
|
||||
return STS_FAILURE;
|
||||
}
|
||||
DEBUGC(DBCLASS_BABBLE,"sendto() call failed:%s",strerror(errno));
|
||||
DEBUGC(DBCLASS_BABBLE,"sendto() [%s:%i] call failed: %s",
|
||||
utils_inet_ntoa(addr), port, strerror(errno));
|
||||
}
|
||||
|
||||
return STS_SUCCESS;
|
||||
|
||||
Reference in New Issue
Block a user