*** empty log message ***
This commit is contained in:
parent
8bcf9e6a2c
commit
bbfdfe25fe
4
AUTHORS
4
AUTHORS
@ -0,0 +1,4 @@
|
||||
Thomas Ries (tries@gmx.net)
|
||||
GnuPG Public Key:
|
||||
pub 1024D/87BCDC94 2000-03-19 Thomas Ries (tries@gmx.net)
|
||||
Key fingerprint = 13D1 19F5 77D0 4CEC 8D3F A24E 09FC C18A 87BC DC94
|
||||
@ -1,7 +1,7 @@
|
||||
|
||||
0.1.1
|
||||
=====
|
||||
- 24-Aug-2002: Imlemented handling of a config file,
|
||||
- 24-Aug-2002: Imlemented support for a config file,
|
||||
obsoletes siproxd_conf.h
|
||||
|
||||
0.1.0
|
||||
|
||||
@ -87,7 +87,7 @@ VERSION = @VERSION@
|
||||
|
||||
SUBDIRS = src doc
|
||||
|
||||
EXTRA_DIST = TODO
|
||||
EXTRA_DIST = TODO RELNOTES
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs
|
||||
CONFIG_HEADER = config.h
|
||||
|
||||
16
README
16
README
@ -1,5 +1,7 @@
|
||||
|
||||
|
||||
Be warned, this (and all the other) documentantation is far from
|
||||
complete. This is just *very* preliminary pre-alpha release. Don't
|
||||
complete. This is just a *very* preliminary pre-alpha release. Don't
|
||||
expect anything!
|
||||
|
||||
|
||||
@ -12,7 +14,7 @@ connections possible via an masquerading firewall.
|
||||
It allows SIP clients (like kphone, linphone) to work behind
|
||||
an IP masquerading firewall or router.
|
||||
|
||||
SIP (Session Initiation Protocol, RFC2543) is used by Softphones
|
||||
SIP (Session Initiation Protocol, RFC3261) is used by Softphones
|
||||
(Voice over IP) to initiate communication. By itself, SIP does not
|
||||
work via masquerading firewalls as the transfered data contains
|
||||
IP addresses and port numbers.
|
||||
@ -46,11 +48,6 @@ How to get started:
|
||||
have dynamic IP addresses, then you might want to use a hostname
|
||||
here and use a dynamic DNS service like dyndns.org)
|
||||
|
||||
!! ACTUALLY, THIS IS NOT YET TRUE. The configuration of INBOUND
|
||||
and OUTBOUND host ist still a compile time issue...
|
||||
Edit the file siproxd_conf.h accordingly. Support for the
|
||||
config file will be very next.
|
||||
|
||||
|
||||
What siproxd does:
|
||||
=================
|
||||
@ -95,4 +92,7 @@ after I made the above change.
|
||||
Contacts:
|
||||
=========
|
||||
|
||||
Thomas Ries <tries@gmx.net>
|
||||
Thomas Ries (tries@gmx.net)
|
||||
GnuPG Public Key:
|
||||
pub 1024D/87BCDC94 2000-03-19 Thomas Ries (tries@gmx.net)
|
||||
Key fingerprint = 13D1 19F5 77D0 4CEC 8D3F A24E 09FC C18A 87BC DC94
|
||||
|
||||
5
TODO
5
TODO
@ -1,8 +1,6 @@
|
||||
TODOs, in anarchistic order:
|
||||
============================
|
||||
|
||||
- support for configuration file!
|
||||
|
||||
|
||||
- 2.2.x kernels:
|
||||
make use of the portfw.so (ipmasqadm package) to create forwarding
|
||||
@ -12,3 +10,6 @@ TODOs, in anarchistic order:
|
||||
- Is there a possibility to open up an masquerading tunnel by
|
||||
a userspace program on the firewall?
|
||||
|
||||
- logging via syslog if running in daemon mode
|
||||
|
||||
- get_ip_by_host: reduce DNS timeouts
|
||||
|
||||
41
src/proxy.c
41
src/proxy.c
@ -79,16 +79,9 @@ int proxy_request (sip_t *request) {
|
||||
type = 0;
|
||||
for (i=0; i<URLMAP_SIZE; i++) {
|
||||
if (urlmap[i].active == 0) continue;
|
||||
/*&&&& comparison of hosts should be based on IP addresses
|
||||
as it looks (at least RQ URI)...*/
|
||||
|
||||
/*&&&& make this comparison into a subroutine - it is used a LOT !
|
||||
also make the HOST comparison more flexible (name<->IP) */
|
||||
/* incomming request ('to' == 'masq') */
|
||||
if ((strcmp(request->to->url->username,
|
||||
urlmap[i].masq_url->username)==0) &&
|
||||
(strcmp(request->to->url->host,
|
||||
urlmap[i].masq_url->host)==0)) {
|
||||
if (compare_url(request->to->url, urlmap[i].masq_url)==0) {
|
||||
type=REQTYP_INCOMMING;
|
||||
DEBUGC(DBCLASS_PROXY,"incomming request from %s@%s from outbound",
|
||||
request->from->url->username,
|
||||
@ -97,10 +90,7 @@ int proxy_request (sip_t *request) {
|
||||
}
|
||||
|
||||
/* outgoing request ('contact' == 'true') */
|
||||
if ((strcmp(contact->url->username,
|
||||
urlmap[i].true_url->username)==0) &&
|
||||
(strcmp(contact->url->host,
|
||||
urlmap[i].true_url->host)==0)) {
|
||||
if (compare_url(contact->url, urlmap[i].true_url)==0) {
|
||||
type=REQTYP_OUTGOING;
|
||||
DEBUGC(DBCLASS_PROXY,"outgoing request from %s@%s from inbound",
|
||||
request->from->url->username,
|
||||
@ -120,7 +110,8 @@ int proxy_request (sip_t *request) {
|
||||
case REQTYP_INCOMMING:
|
||||
/* rewrite request URI to point to the real host */
|
||||
/* i still holds the valid index into the URLMAP table */
|
||||
/* THIS IS UGLY!!! I dont like it &&&&&&*/
|
||||
|
||||
/* THIS IS UGLY!!! I dont like it */
|
||||
DEBUGC(DBCLASS_PROXY,"rewriting incomming Request URI");
|
||||
url=msg_geturi(request);
|
||||
free(url->host);url->host=NULL;
|
||||
@ -160,19 +151,13 @@ int proxy_request (sip_t *request) {
|
||||
/* get target address from request URL */
|
||||
url=msg_geturi(request);
|
||||
|
||||
#if EXP1
|
||||
/* &&&& linphone 0.9.0pre4
|
||||
#ifdef HACK1
|
||||
/* linphone-0.9.0pre4
|
||||
take To address and place it into URI (at least the host part)
|
||||
Linphone 0.9.0pre4 puts the proxy host in the request URI
|
||||
Linphone-0.9.0pre4 puts the proxy host in the request URI
|
||||
if OUTBOUNT proxy is activated!
|
||||
|
||||
This is only a hack to recreate the proper final request URI.
|
||||
see linphone, osipdialog.c line 1172
|
||||
if (call_leg->peer == NULL)
|
||||
url_2char (call_leg->to->url, &tmp);
|
||||
else
|
||||
url_2char (call_leg->peer->url, &tmp);
|
||||
url_parse (sipmsg->strtline->rquri, tmp); <<<<----
|
||||
This issue has been fixed in 0.9.1pre1
|
||||
*/
|
||||
{
|
||||
header_t *header_ua;
|
||||
@ -259,10 +244,7 @@ int proxy_response (sip_t *response) {
|
||||
|
||||
|
||||
/* incomming response ('from' == 'masq') */
|
||||
if ((strcmp(response->from->url->username,
|
||||
urlmap[i].masq_url->username)==0) &&
|
||||
(strcmp(response->from->url->host,
|
||||
urlmap[i].masq_url->host)==0)) {
|
||||
if (compare_url(response->from->url, urlmap[i].masq_url)==0) {
|
||||
type=RESTYP_INCOMMING;
|
||||
DEBUGC(DBCLASS_PROXY,"incomming response for %s@%s from outbound",
|
||||
response->from->url->username,
|
||||
@ -271,10 +253,7 @@ int proxy_response (sip_t *response) {
|
||||
}
|
||||
|
||||
/* outgoing response ('to' == 'masq') */
|
||||
if ((strcmp(response->to->url->username,
|
||||
urlmap[i].masq_url->username)==0) &&
|
||||
(strcmp(response->to->url->host,
|
||||
urlmap[i].masq_url->host)==0)) {
|
||||
if (compare_url(response->to->url, urlmap[i].masq_url)==0) {
|
||||
type=RESTYP_OUTGOING;
|
||||
DEBUGC(DBCLASS_PROXY,"outgoing response for %s@%s from inbound",
|
||||
response->from->url->username,
|
||||
|
||||
@ -109,8 +109,7 @@ int register_client(sip_t *my_msg) {
|
||||
url2_to=urlmap[i].masq_url;
|
||||
url2_contact=urlmap[i].true_url;
|
||||
|
||||
if ( (strcmp(url1_to->username, url2_to->username )==0) &&
|
||||
(strcmp(url1_to->host, url2_to->host )==0) &&
|
||||
if ( (compare_url(url1_to, url2_to)==0) &&
|
||||
(strcmp(url1_contact->username, url2_contact->username)==0) &&
|
||||
(strcmp(url1_contact->host, url2_contact->host )==0) ) {
|
||||
DEBUGC(DBCLASS_REG, "found entry for %s@%s at slot=%i, exp=%li",
|
||||
|
||||
@ -120,7 +120,7 @@ int main (int argc, char *argv[])
|
||||
/* listen for incomming messages */
|
||||
sipsock_listen();
|
||||
|
||||
/*&&&& daemonize !! */
|
||||
/* daemonize if requested to */
|
||||
if (configuration.daemonize) {
|
||||
DEBUGC(DBCLASS_CONFIG,"daemonizing");
|
||||
if (fork()!=0) exit(0);
|
||||
@ -129,8 +129,6 @@ int main (int argc, char *argv[])
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Main loop
|
||||
*/
|
||||
|
||||
@ -45,6 +45,7 @@ sip_t * msg_make_template_reply (sip_t * request, int code);
|
||||
int check_vialoop (sip_t *my_msg);
|
||||
int is_via_local (via_t *via);
|
||||
int get_ip_by_host(char *hostname, struct in_addr *addr);
|
||||
int compare_url(url_t *url1, url_t *url2);
|
||||
|
||||
/* config.c */
|
||||
int read_config(char *name, int search);
|
||||
@ -77,20 +78,23 @@ struct siproxd_config {
|
||||
/*
|
||||
* some constant definitions
|
||||
*/
|
||||
#define URLMAP_SIZE 128 // size of URL mapping table
|
||||
#define BUFFER_SIZE 1024 // input buffer for read from socket
|
||||
#define URL_STRING_SIZE 128 //
|
||||
|
||||
#define SIP_PORT 5060
|
||||
|
||||
#define URLMAP_SIZE 128 // size of URL mapping table
|
||||
#define BUFFER_SIZE 1024 // input buffer for read from socket
|
||||
#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 32 // number of entries in internal DNS cache
|
||||
#define DNS_MAX_AGE 60 // maximum age of an cache entry (sec)
|
||||
#define HOSTNAME_SIZE 32 // max string length of a hostname
|
||||
|
||||
/*
|
||||
* optionasl hacks
|
||||
* optional hacks
|
||||
*/
|
||||
#define EXP1 1 /* HACK linphone0.9.0pre4 */
|
||||
#define HACK1 /* linphone-0.9.0pre4: broken RQ URI hack */
|
||||
/* 14-Aug-2002 TR
|
||||
Linphone puts in the proxies hostname in the request URI when
|
||||
OUTBOUND proxy is activated. But ONLY the hostname. Username and
|
||||
Port (!!!) are kept from the SIP address givven by the user.
|
||||
This is a BUG in my eyes. Linphone must send the datagrap to
|
||||
the Proxy, but have the final receiver in the request URI !
|
||||
Port (!!!) are kept from the SIP address given by the user.
|
||||
This issue is fixed in linphone-0.9.1pre1
|
||||
*/
|
||||
|
||||
113
src/utils.c
113
src/utils.c
@ -21,6 +21,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <netinet/in.h>
|
||||
@ -41,6 +42,9 @@ extern struct siproxd_config configuration;
|
||||
|
||||
extern int h_errno;
|
||||
|
||||
/*
|
||||
* create a reply template from an given SIP request
|
||||
*/
|
||||
sip_t *msg_make_template_reply (sip_t * request, int code) {
|
||||
sip_t *response;
|
||||
char *tmp;
|
||||
@ -48,8 +52,8 @@ sip_t *msg_make_template_reply (sip_t * request, int code) {
|
||||
|
||||
msg_init (&response);
|
||||
msg_setversion (response, sgetcopy ("SIP/2.0"));
|
||||
tmp = malloc(5);
|
||||
snprintf (tmp, 5, "%i", code);
|
||||
tmp = malloc(STATUSCODE_SIZE);
|
||||
snprintf (tmp, STATUSCODE_SIZE, "%i", code);
|
||||
msg_setstatuscode (response, tmp);
|
||||
msg_setreasonphrase (response, msg_getreason (code));
|
||||
|
||||
@ -76,6 +80,11 @@ sip_t *msg_make_template_reply (sip_t * request, int code) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* check for a via loop.
|
||||
* It checks for the presense of a via entry that holds one of
|
||||
* my IP addresses and is *not* the topmost via.
|
||||
*/
|
||||
int check_vialoop (sip_t *my_msg) {
|
||||
int sts;
|
||||
int pos;
|
||||
@ -95,6 +104,10 @@ int check_vialoop (sip_t *my_msg) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* check if a given via_t is local. I.e. its address is owned
|
||||
* by my inbound or outbound interface
|
||||
*/
|
||||
int is_via_local (via_t *via) {
|
||||
int sts;
|
||||
struct in_addr addr_via, addr_myself;
|
||||
@ -109,10 +122,6 @@ int is_via_local (via_t *via) {
|
||||
get_ip_by_host(via->host, &addr_via);
|
||||
}
|
||||
|
||||
/* make this more optimized!!
|
||||
do the lookup at the beginning and then compare against all
|
||||
the via entries !
|
||||
*/
|
||||
sts=0;
|
||||
for (i=0; ; i++) {
|
||||
ptr=my_hostnames[i];
|
||||
@ -131,11 +140,52 @@ the via entries !
|
||||
return sts;
|
||||
}
|
||||
|
||||
int get_ip_by_host(char *hostname, struct in_addr *addr) {
|
||||
struct hostent *hostentry;
|
||||
/* &&&& bahh, figure out a way to make this stuff non-blocking*/
|
||||
/* an asynchronous name-resolving might be neat */
|
||||
|
||||
/*
|
||||
* resolve a hostname and return in_addr
|
||||
* handles its own little DNS cache.
|
||||
*/
|
||||
int get_ip_by_host(char *hostname, struct in_addr *addr) {
|
||||
int i, j;
|
||||
time_t t;
|
||||
struct hostent *hostentry;
|
||||
static struct {
|
||||
time_t timestamp;
|
||||
struct in_addr addr;
|
||||
char hostname[HOSTNAME_SIZE];
|
||||
} dns_cache[DNS_CACHE_SIZE];
|
||||
static int cache_initialized=0;
|
||||
|
||||
/* first time: initialize DNS cache */
|
||||
if (cache_initialized == 0) {
|
||||
DEBUGC(DBCLASS_DNS, "initializing DNS cache (%i entries)", DNS_CACHE_SIZE);
|
||||
memset(dns_cache, 0, sizeof(dns_cache));
|
||||
cache_initialized=1;
|
||||
}
|
||||
|
||||
time(&t);
|
||||
/* clean expired entries */
|
||||
for (i=0; i<DNS_CACHE_SIZE; i++) {
|
||||
if ( (dns_cache[i].timestamp+DNS_MAX_AGE) < t ) {
|
||||
DEBUGC(DBCLASS_DNS, "cleaning DNS cache, entry %i)", i);
|
||||
memset (&dns_cache[i], 0, sizeof(dns_cache[0]));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* search requested entry in cache
|
||||
*/
|
||||
for (i=0; i<DNS_CACHE_SIZE; i++) {
|
||||
if (dns_cache[i].hostname[0]=='\0') continue; /* empty */
|
||||
if (strcmp(hostname, dns_cache[i].hostname) == 0) { /* match */
|
||||
memcpy(addr, &dns_cache[i].addr, sizeof(struct in_addr));
|
||||
DEBUGC(DBCLASS_DNS, "from cache: %s -> %s",
|
||||
hostname, inet_ntoa(*addr));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* did not find it in cache, so I have to resolve it */
|
||||
hostentry=gethostbyname(hostname);
|
||||
|
||||
if (hostentry==NULL) {
|
||||
@ -144,9 +194,50 @@ int get_ip_by_host(char *hostname, struct in_addr *addr) {
|
||||
}
|
||||
|
||||
memcpy(addr, hostentry->h_addr, sizeof(struct in_addr));
|
||||
DEBUGC(DBCLASS_BABBLE, "resolved: %s -> %s", hostname, inet_ntoa(*addr));
|
||||
DEBUGC(DBCLASS_DNS, "resolved: %s -> %s", hostname, inet_ntoa(*addr));
|
||||
|
||||
/*
|
||||
* remember the result in the cache
|
||||
*/
|
||||
/* find an empty slot */
|
||||
j=0;
|
||||
for (i=0; i<DNS_CACHE_SIZE; i++) {
|
||||
if (dns_cache[i].hostname[0]=='\0') break;
|
||||
if (dns_cache[i].timestamp < t) {
|
||||
/* remember oldest entry */
|
||||
t=dns_cache[i].timestamp;
|
||||
j=i;
|
||||
}
|
||||
}
|
||||
/* if no empty slot found, take oldest one */
|
||||
if (i >= DNS_CACHE_SIZE) i=j;
|
||||
|
||||
/* store in cache */
|
||||
DEBUGC(DBCLASS_DNS, "store into DNS cache, entry %i)", i);
|
||||
memset(&dns_cache[i], 0, sizeof(dns_cache[0]));
|
||||
strncpy(dns_cache[i].hostname, hostname, HOSTNAME_SIZE);
|
||||
time(&dns_cache[i].timestamp);
|
||||
memcpy(&dns_cache[i].addr, addr, sizeof(struct in_addr));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* compares two URLs
|
||||
* returns 0 if equal, >0 if non equal, <0 if error
|
||||
* (by now, only hostname and username are compared)
|
||||
*/
|
||||
int compare_url(url_t *url1, url_t *url2) {
|
||||
int sts;
|
||||
/* comparison of hosts should be based on IP addresses, no? */
|
||||
DEBUGC(DBCLASS_BABBLE, "comparng urls: %s@%s -> %s@%s",
|
||||
url1->username, url1->host, url2->username, url2->host);
|
||||
if ((strcmp(url1->username, url2->username)==0) &&
|
||||
(strcmp(url1->host, url2->host)==0)) {
|
||||
sts = 0;
|
||||
} else {
|
||||
sts = -1;
|
||||
}
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user