- SDP rewrite: properly handle 'c=' items in session

*and* media part of SDP data.
- migrated config.h.in by new version of autoconf (Fedora core1)
This commit is contained in:
Thomas Ries
2004-03-27 10:20:22 +00:00
parent 62b4f95e8d
commit 2fba2bcb3b
3 changed files with 347 additions and 243 deletions
+2
View File
@@ -1,5 +1,7 @@
0.5.5
=====
26-Mar-2004: - SDP rewrite: properly handle 'c=' items in session
*and* media part of SDP data.
22-Mar-2004: - deal with wildcard Contact header for unREGISTER
- enhanced security tests to survive the PROTOS test
21-Mar-2004: - added ./autogen.sh
+199 -170
View File
@@ -1,210 +1,239 @@
/* config.h.in. Generated automatically from configure.in by autoheader. */
/* config.h.in. Generated from configure.in by autoheader. */
/* Define to empty if the keyword does not work. */
#undef const
/* Define if you don't have vprintf but do have _doprnt. */
#undef HAVE_DOPRNT
/* Define if you have the vprintf function. */
#undef HAVE_VPRINTF
/* Define to `unsigned' if <sys/types.h> doesn't define. */
#undef size_t
/* Define if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME
/* Define if your <sys/time.h> declares struct tm. */
#undef TM_IN_SYS_TIME
/* Define if you have the bind function. */
/* Define to 1 if you have the `bind' function. */
#undef HAVE_BIND
/* Define if you have the chroot function. */
/* Define to 1 if you have the `chroot' function. */
#undef HAVE_CHROOT
/* Define if you have the fcntl function. */
#undef HAVE_FCNTL
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
#undef HAVE_DOPRNT
/* Define if you have the fgets function. */
#undef HAVE_FGETS
/* Define if you have the getgid function. */
#undef HAVE_GETGID
/* Define if you have the gethostbyname function. */
#undef HAVE_GETHOSTBYNAME
/* Define if you have the gethostbyname_r function. */
#undef HAVE_GETHOSTBYNAME_R
/* Define if you have the getopt_long function. */
#undef HAVE_GETOPT_LONG
/* Define if you have the getpwnam function. */
#undef HAVE_GETPWNAM
/* Define if you have the getuid function. */
#undef HAVE_GETUID
/* Define if you have the hstrerror function. */
#undef HAVE_HSTRERROR
/* Define if you have the inet_aton function. */
#undef HAVE_INET_ATON
/* Define if you have the inet_ntoa function. */
#undef HAVE_INET_NTOA
/* Define if you have the inet_ntop function. */
#undef HAVE_INET_NTOP
/* Define if you have the inet_pton function. */
#undef HAVE_INET_PTON
/* Define if you have the read function. */
#undef HAVE_READ
/* Define if you have the select function. */
#undef HAVE_SELECT
/* Define if you have the send function. */
#undef HAVE_SEND
/* Define if you have the sendto function. */
#undef HAVE_SENDTO
/* Define if you have the setgid function. */
#undef HAVE_SETGID
/* Define if you have the setsid function. */
#undef HAVE_SETSID
/* Define if you have the setuid function. */
#undef HAVE_SETUID
/* Define if you have the socket function. */
#undef HAVE_SOCKET
/* Define if you have the sprintf function. */
#undef HAVE_SPRINTF
/* Define if you have the sscanf function. */
#undef HAVE_SSCANF
/* Define if you have the strchr function. */
#undef HAVE_STRCHR
/* Define if you have the strerror function. */
#undef HAVE_STRERROR
/* Define if you have the strncpy function. */
#undef HAVE_STRNCPY
/* Define if you have the strstr function. */
#undef HAVE_STRSTR
/* Define if you have the syslog function. */
#undef HAVE_SYSLOG
/* Define if you have the vfprintf function. */
#undef HAVE_VFPRINTF
/* Define if you have the vsnprintf function. */
#undef HAVE_VSNPRINTF
/* Define if you have the <errno.h> header file. */
/* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
/* Define if you have the <getopt.h> header file. */
/* Define to 1 if you have the `fcntl' function. */
#undef HAVE_FCNTL
/* Define to 1 if you have the `fgets' function. */
#undef HAVE_FGETS
/* gethostbyname_r takes 3 arguments */
#undef HAVE_FUNC_GETHOSTBYNAME_R_3
/* gethostbyname_r takes 5 arguments */
#undef HAVE_FUNC_GETHOSTBYNAME_R_5
/* gethostbyname_r takes 6 arguments */
#undef HAVE_FUNC_GETHOSTBYNAME_R_6
/* Define to 1 if you have the `getgid' function. */
#undef HAVE_GETGID
/* Define to 1 if you have the `gethostbyname' function. */
#undef HAVE_GETHOSTBYNAME
/* Define to 1 if you have the `gethostbyname_r' function. */
#undef HAVE_GETHOSTBYNAME_R
/* Define to 1 if you have the <getopt.h> header file. */
#undef HAVE_GETOPT_H
/* Define if you have the <linux/ip_masq.h> header file. */
#undef HAVE_LINUX_IP_MASQ_H
/* Define to 1 if you have the `getopt_long' function. */
#undef HAVE_GETOPT_LONG
/* Define if you have the <linux/netfilter.h> header file. */
#undef HAVE_LINUX_NETFILTER_H
/* Define to 1 if you have the `getpwnam' function. */
#undef HAVE_GETPWNAM
/* Define if you have the <pwd.h> header file. */
#undef HAVE_PWD_H
/* Define to 1 if you have the `getuid' function. */
#undef HAVE_GETUID
/* Define if you have the <stdarg.h> header file. */
#undef HAVE_STDARG_H
/* Define to 1 if you have the `hstrerror' function. */
#undef HAVE_HSTRERROR
/* Define if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define to 1 if you have the `inet_aton' function. */
#undef HAVE_INET_ATON
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the `inet_ntoa' function. */
#undef HAVE_INET_NTOA
/* Define if you have the <varargs.h> header file. */
#undef HAVE_VARARGS_H
/* Define to 1 if you have the `inet_ntop' function. */
#undef HAVE_INET_NTOP
/* Define if you have the osip2 library (-losip2). */
/* Define to 1 if you have the `inet_pton' function. */
#undef HAVE_INET_PTON
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `osip2' library (-losip2). */
#undef HAVE_LIBOSIP2
/* Define if you have the osipparser2 library (-losipparser2). */
/* Define to 1 if you have the `osipparser2' library (-losipparser2). */
#undef HAVE_LIBOSIPPARSER2
/* Define to 1 if you have the <linux/ip_masq.h> header file. */
#undef HAVE_LINUX_IP_MASQ_H
/* Define to 1 if you have the <linux/netfilter.h> header file. */
#undef HAVE_LINUX_NETFILTER_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define if you have POSIX threads libraries and header files. */
#undef HAVE_PTHREAD
/* Define to 1 if you have the <pwd.h> header file. */
#undef HAVE_PWD_H
/* Define to 1 if you have the `read' function. */
#undef HAVE_READ
/* Define to 1 if you have the `select' function. */
#undef HAVE_SELECT
/* Define to 1 if you have the `send' function. */
#undef HAVE_SEND
/* Define to 1 if you have the `sendto' function. */
#undef HAVE_SENDTO
/* Define to 1 if you have the `setgid' function. */
#undef HAVE_SETGID
/* Define to 1 if you have the `setsid' function. */
#undef HAVE_SETSID
/* Define to 1 if you have the `setuid' function. */
#undef HAVE_SETUID
/* Define to 1 if you have the `socket' function. */
#undef HAVE_SOCKET
/* Define to 1 if you have the `sprintf' function. */
#undef HAVE_SPRINTF
/* Define to 1 if you have the `sscanf' function. */
#undef HAVE_SSCANF
/* Define to 1 if you have the <stdarg.h> header file. */
#undef HAVE_STDARG_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strchr' function. */
#undef HAVE_STRCHR
/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strncpy' function. */
#undef HAVE_STRNCPY
/* Define to 1 if you have the `strstr' function. */
#undef HAVE_STRSTR
/* Define to 1 if you have the `syslog' function. */
#undef HAVE_SYSLOG
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the <varargs.h> header file. */
#undef HAVE_VARARGS_H
/* Define to 1 if you have the `vfprintf' function. */
#undef HAVE_VFPRINTF
/* Define to 1 if you have the `vprintf' function. */
#undef HAVE_VPRINTF
/* Define to 1 if you have the `vsnprintf' function. */
#undef HAVE_VSNPRINTF
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to the necessary symbol if this constant uses a non-standard name on
your system. */
#undef PTHREAD_CREATE_JOINABLE
/* will search for config file here */
#undef SIPROXDCONFPATH
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
#undef TM_IN_SYS_TIME
/* Version number of package */
#undef VERSION
/* building on Linux platform */
#undef _LINUX
/* building on BSD platform */
#undef _BSD
/* building on FreeBSD platform */
#undef _FREEBSD
/* building on BSD platform */
#undef _BSD
/* building on OpenBSD platform */
#undef _OPENBSD
/* building on BSD platform */
#undef _BSD
/* building on NetBSD platform */
#undef _NETBSD
/* building on BSD platform */
#undef _BSD
/* building on BSD/OS platform */
#undef _BSDOS
/* building on FreeBSD platform */
#undef _FREEBSD
/* building on Linux platform */
#undef _LINUX
/* building on NetBSD platform */
#undef _NETBSD
/* building on OpenBSD platform */
#undef _OPENBSD
/* building on Solaris2 platform */
#undef _SOLARIS2
/* Define to the necessary symbol if this constant
uses a non-standard name on your system. */
#undef PTHREAD_CREATE_JOINABLE
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define if you have POSIX threads libraries and header files. */
#undef HAVE_PTHREAD
/* Define to `unsigned' if <sys/types.h> does not define. */
#undef size_t
/* typedef socklen_t available */
#undef socklen_t
/* gethostbyname_r takes 6 arguments */
#undef HAVE_FUNC_GETHOSTBYNAME_R_6
/* gethostbyname_r takes 5 arguments */
#undef HAVE_FUNC_GETHOSTBYNAME_R_5
/* gethostbyname_r takes 3 arguments */
#undef HAVE_FUNC_GETHOSTBYNAME_R_3
/* will search for config file here */
#undef SIPROXDCONFPATH
+146 -73
View File
@@ -831,7 +831,7 @@ int proxy_response (osip_message_t *response, struct sockaddr_in *from) {
int proxy_rewrite_invitation_body(osip_message_t *mymsg, int direction){
osip_body_t *body;
sdp_message_t *sdp;
struct in_addr map_addr, msg_addr, outside_addr, inside_addr;
struct in_addr map_addr, addr_sess, addr_media, outside_addr, inside_addr;
int sts;
char *bodybuff;
char clen[8]; /* content length: probably never more than 7 digits !*/
@@ -840,10 +840,15 @@ int proxy_rewrite_invitation_body(osip_message_t *mymsg, int direction){
sdp_connection_t *sdp_conn;
sdp_media_t *sdp_med;
int rtp_direction=0;
int have_c_session=0;
int have_c_media=0;
if (configuration.rtp_proxy_enable == 0) return STS_SUCCESS;
/*
* get SDP structure
*/
have_c_session=0;
sts = osip_message_get_body(mymsg, 0, &body);
if (sts != 0) {
if ((MSG_IS_RESPONSE_FOR(mymsg,"INVITE")) &&
@@ -857,6 +862,8 @@ int proxy_rewrite_invitation_body(osip_message_t *mymsg, int direction){
ERROR("rewrite_invitation_body: no body found in message");
return STS_FAILURE;
}
} else {
have_c_session=1;
}
sts = osip_body_to_str(body, &bodybuff);
@@ -886,14 +893,8 @@ 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), &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));
sdp_message_free(sdp);
return STS_FAILURE;
}
/* get outbound address */
sts = get_ip_by_ifname(configuration.outbound_if, &outside_addr);
if (sts == STS_FAILURE) {
ERROR("can't find outbound interface %s - configuration error?",
@@ -901,6 +902,8 @@ if (configuration.debuglevel)
sdp_message_free(sdp);
return STS_FAILURE;
}
/* get inbound address */
sts = get_ip_by_ifname(configuration.inbound_if, &inside_addr);
if (sts == STS_FAILURE) {
ERROR("can't find inbound interface %s - configuration error?",
@@ -928,84 +931,154 @@ if (configuration.debuglevel)
}
}
/*
* rewrite c= address
* !! an IP address of 0.0.0.0 means *MUTE*, don't rewrite such one
* first, check presence of a 'c=' item on session level
*/
sdp_conn = sdp_message_connection_get (sdp, -1, 0);
if (sdp_conn && sdp_conn->c_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));
if (sdp->c_connection==NULL || sdp->c_connection->c_addr==NULL) {
/*
* No 'c=' on session level, search on media level now
*
* According to RFC2327, ALL media description must
* include a 'c=' item now:
*/
media_stream_no=0;
while (!sdp_message_endof_media(sdp, media_stream_no)) {
/* check if n'th media stream is present */
if (sdp_message_c_addr_get(sdp, media_stream_no, 0) == NULL) {
ERROR("SDP: have no 'c=' on session level and neither "
"on media level (media=%i)",media_stream_no);
sdp_message_free(sdp);
return STS_FAILURE;
}
media_stream_no++;
} /* while */
}
/* Required 'c=' items ARE present */
/*
* rewrite 'c=' item on session level if present and not yet done.
* remember the original address in addr_sess
*/
memset(&addr_sess, 0, sizeof(addr_sess));
if (have_c_session == 1){
DEBUG("*0 session conn=%s", sdp->c_connection->c_addr);
sts = get_ip_by_host(sdp->c_connection->c_addr, &addr_sess);
if (sts == STS_FAILURE) {
ERROR("SDP: cannot resolve session 'c=' host [%s]",
sdp->c_connection->c_addr);
sdp_message_free(sdp);
return STS_FAILURE;
}
/*
* Rewrite
* an IP address of 0.0.0.0 means *MUTE*, don't rewrite such
*/
if (strcmp(sdp->c_connection->c_addr, "0.0.0.0") != 0) {
osip_free(sdp->c_connection->c_addr);
sdp->c_connection->c_addr=osip_malloc(HOSTNAME_SIZE);
sprintf(sdp->c_connection->c_addr, "%s", utils_inet_ntoa(map_addr));
DEBUG("*0 rewritten: session conn=%s", sdp->c_connection->c_addr);
} else {
/* 0.0.0.0 - don't rewrite */
DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: got a MUTE c= record");
DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: "
"got a MUTE c= record (on session level - legal?)");
}
} else {
ERROR("got NULL c= address record - can't rewrite");
}
/*
* loop through all m= descritions,
* loop through all media descritions,
* start RTP proxy and rewrite them
*/
if (configuration.rtp_proxy_enable == 1) {
for (media_stream_no=0;;media_stream_no++) {
/* check if n'th media stream is present */
if (sdp_message_m_port_get(sdp, media_stream_no) == NULL) break;
for (media_stream_no=0;;media_stream_no++) {
/* check if n'th media stream is present */
if (sdp_message_m_port_get(sdp, media_stream_no) == NULL) break;
/* start an RTP proxying stream */
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) {
osip_uri_t *cont_url = NULL;
char *client_id=NULL;
/* try to get some additional UA specific unique ID.
* Try:
* 1) User part of Contact header
* 2) Host part of Contact header (will be different
* between internal UA and external UA)
*/
if (!osip_list_eol(mymsg->contacts, 0))
cont_url = ((osip_contact_t*)(mymsg->contacts->node->element))->url;
if (cont_url) {
client_id=cont_url->username;
if (client_id == NULL) client_id=cont_url->host;
}
sts = rtp_start_fwd(osip_message_get_call_id(mymsg),
client_id,
rtp_direction,
media_stream_no,
map_addr, &map_port,
msg_addr, msg_port);
if (sts == STS_SUCCESS) {
/* 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); /* 5 digits, \0 + align */
sprintf(sdp_med->m_port, "%i", map_port);
DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: "
"m= rewrote port to [%i]",map_port);
} else {
ERROR("rewriting port in m= failed sdp_med=%p, "
"m_number_of_port=%p", sdp_med, sdp_med->m_port);
}
} /* sts == success */
} /* if msg_port > 0 */
/*
* check if a 'c=' item is present in this media description,
* if so -> rewrite it
*/
DEBUG("*0 msn=%i", media_stream_no);
memset(&addr_media, 0, sizeof(addr_media));
have_c_media=0;
sdp_conn=sdp_message_connection_get(sdp, media_stream_no, 0);
if (sdp_conn && sdp_conn->c_addr) {
DEBUG("*1 msn=%i, host=%s", media_stream_no, sdp_conn->c_addr);
if (strcmp(sdp_conn->c_addr, "0.0.0.0") != 0) {
sts = get_ip_by_host(sdp_conn->c_addr, &addr_media);
have_c_media=1;
/* 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 {
/* no port defined - skip entry */
WARN("no port defined in m=(media) stream_no=%i", media_stream_no);
continue;
/* 0.0.0.0 - don't rewrite */
DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: got a "
"MUTE c= record (media level)");
}
} /* for media_stream_no */
} /* if rtp_proxy_enable */
}
/* start an RTP proxying stream */
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) {
osip_uri_t *cont_url = NULL;
char *client_id=NULL;
/* try to get some additional UA specific unique ID.
* Try:
* 1) User part of Contact header
* 2) Host part of Contact header (will be different
* between internal UA and external UA)
*/
if (!osip_list_eol(mymsg->contacts, 0))
cont_url = ((osip_contact_t*)(mymsg->contacts->node->element))->url;
if (cont_url) {
client_id=cont_url->username;
if (client_id == NULL) client_id=cont_url->host;
}
/*
* do we have a 'c=' item on media level?
* if not, use the same as on session level
*/
if (have_c_media == 0) {
memcpy(&addr_media, &addr_sess, sizeof(addr_sess));
}
sts = rtp_start_fwd(osip_message_get_call_id(mymsg),
client_id,
rtp_direction,
media_stream_no,
map_addr, &map_port,
addr_media, msg_port);
if (sts == STS_SUCCESS) {
/* 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); /* 5 digits, \0 + align */
sprintf(sdp_med->m_port, "%i", map_port);
DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: "
"m= rewrote port to [%i]",map_port);
} else {
ERROR("rewriting port in m= failed sdp_med=%p, "
"m_number_of_port=%p", sdp_med, sdp_med->m_port);
}
} /* sts == success */
} /* if msg_port > 0 */
} else {
/* no port defined - skip entry */
WARN("no port defined in m=(media) stream_no=%i", media_stream_no);
continue;
}
} /* for media_stream_no */
/* remove old body */
sts = osip_list_remove(mymsg->bodies, 0);