*** 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
|
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
|
obsoletes siproxd_conf.h
|
||||||
|
|
||||||
0.1.0
|
0.1.0
|
||||||
|
|||||||
@ -87,7 +87,7 @@ VERSION = @VERSION@
|
|||||||
|
|
||||||
SUBDIRS = src doc
|
SUBDIRS = src doc
|
||||||
|
|
||||||
EXTRA_DIST = TODO
|
EXTRA_DIST = TODO RELNOTES
|
||||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||||
mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs
|
mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs
|
||||||
CONFIG_HEADER = config.h
|
CONFIG_HEADER = config.h
|
||||||
|
|||||||
16
README
16
README
@ -1,5 +1,7 @@
|
|||||||
|
|
||||||
|
|
||||||
Be warned, this (and all the other) documentantation is far from
|
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!
|
expect anything!
|
||||||
|
|
||||||
|
|
||||||
@ -12,7 +14,7 @@ connections possible via an masquerading firewall.
|
|||||||
It allows SIP clients (like kphone, linphone) to work behind
|
It allows SIP clients (like kphone, linphone) to work behind
|
||||||
an IP masquerading firewall or router.
|
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
|
(Voice over IP) to initiate communication. By itself, SIP does not
|
||||||
work via masquerading firewalls as the transfered data contains
|
work via masquerading firewalls as the transfered data contains
|
||||||
IP addresses and port numbers.
|
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
|
have dynamic IP addresses, then you might want to use a hostname
|
||||||
here and use a dynamic DNS service like dyndns.org)
|
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:
|
What siproxd does:
|
||||||
=================
|
=================
|
||||||
@ -95,4 +92,7 @@ after I made the above change.
|
|||||||
Contacts:
|
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:
|
TODOs, in anarchistic order:
|
||||||
============================
|
============================
|
||||||
|
|
||||||
- support for configuration file!
|
|
||||||
|
|
||||||
|
|
||||||
- 2.2.x kernels:
|
- 2.2.x kernels:
|
||||||
make use of the portfw.so (ipmasqadm package) to create forwarding
|
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
|
- Is there a possibility to open up an masquerading tunnel by
|
||||||
a userspace program on the firewall?
|
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;
|
type = 0;
|
||||||
for (i=0; i<URLMAP_SIZE; i++) {
|
for (i=0; i<URLMAP_SIZE; i++) {
|
||||||
if (urlmap[i].active == 0) continue;
|
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') */
|
/* incomming request ('to' == 'masq') */
|
||||||
if ((strcmp(request->to->url->username,
|
if (compare_url(request->to->url, urlmap[i].masq_url)==0) {
|
||||||
urlmap[i].masq_url->username)==0) &&
|
|
||||||
(strcmp(request->to->url->host,
|
|
||||||
urlmap[i].masq_url->host)==0)) {
|
|
||||||
type=REQTYP_INCOMMING;
|
type=REQTYP_INCOMMING;
|
||||||
DEBUGC(DBCLASS_PROXY,"incomming request from %s@%s from outbound",
|
DEBUGC(DBCLASS_PROXY,"incomming request from %s@%s from outbound",
|
||||||
request->from->url->username,
|
request->from->url->username,
|
||||||
@ -97,10 +90,7 @@ int proxy_request (sip_t *request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* outgoing request ('contact' == 'true') */
|
/* outgoing request ('contact' == 'true') */
|
||||||
if ((strcmp(contact->url->username,
|
if (compare_url(contact->url, urlmap[i].true_url)==0) {
|
||||||
urlmap[i].true_url->username)==0) &&
|
|
||||||
(strcmp(contact->url->host,
|
|
||||||
urlmap[i].true_url->host)==0)) {
|
|
||||||
type=REQTYP_OUTGOING;
|
type=REQTYP_OUTGOING;
|
||||||
DEBUGC(DBCLASS_PROXY,"outgoing request from %s@%s from inbound",
|
DEBUGC(DBCLASS_PROXY,"outgoing request from %s@%s from inbound",
|
||||||
request->from->url->username,
|
request->from->url->username,
|
||||||
@ -120,7 +110,8 @@ int proxy_request (sip_t *request) {
|
|||||||
case REQTYP_INCOMMING:
|
case REQTYP_INCOMMING:
|
||||||
/* rewrite request URI to point to the real host */
|
/* rewrite request URI to point to the real host */
|
||||||
/* i still holds the valid index into the URLMAP table */
|
/* 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");
|
DEBUGC(DBCLASS_PROXY,"rewriting incomming Request URI");
|
||||||
url=msg_geturi(request);
|
url=msg_geturi(request);
|
||||||
free(url->host);url->host=NULL;
|
free(url->host);url->host=NULL;
|
||||||
@ -160,19 +151,13 @@ int proxy_request (sip_t *request) {
|
|||||||
/* get target address from request URL */
|
/* get target address from request URL */
|
||||||
url=msg_geturi(request);
|
url=msg_geturi(request);
|
||||||
|
|
||||||
#if EXP1
|
#ifdef HACK1
|
||||||
/* &&&& linphone 0.9.0pre4
|
/* linphone-0.9.0pre4
|
||||||
take To address and place it into URI (at least the host part)
|
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!
|
if OUTBOUNT proxy is activated!
|
||||||
|
|
||||||
This is only a hack to recreate the proper final request URI.
|
This is only a hack to recreate the proper final request URI.
|
||||||
see linphone, osipdialog.c line 1172
|
This issue has been fixed in 0.9.1pre1
|
||||||
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); <<<<----
|
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
header_t *header_ua;
|
header_t *header_ua;
|
||||||
@ -259,10 +244,7 @@ int proxy_response (sip_t *response) {
|
|||||||
|
|
||||||
|
|
||||||
/* incomming response ('from' == 'masq') */
|
/* incomming response ('from' == 'masq') */
|
||||||
if ((strcmp(response->from->url->username,
|
if (compare_url(response->from->url, urlmap[i].masq_url)==0) {
|
||||||
urlmap[i].masq_url->username)==0) &&
|
|
||||||
(strcmp(response->from->url->host,
|
|
||||||
urlmap[i].masq_url->host)==0)) {
|
|
||||||
type=RESTYP_INCOMMING;
|
type=RESTYP_INCOMMING;
|
||||||
DEBUGC(DBCLASS_PROXY,"incomming response for %s@%s from outbound",
|
DEBUGC(DBCLASS_PROXY,"incomming response for %s@%s from outbound",
|
||||||
response->from->url->username,
|
response->from->url->username,
|
||||||
@ -271,10 +253,7 @@ int proxy_response (sip_t *response) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* outgoing response ('to' == 'masq') */
|
/* outgoing response ('to' == 'masq') */
|
||||||
if ((strcmp(response->to->url->username,
|
if (compare_url(response->to->url, urlmap[i].masq_url)==0) {
|
||||||
urlmap[i].masq_url->username)==0) &&
|
|
||||||
(strcmp(response->to->url->host,
|
|
||||||
urlmap[i].masq_url->host)==0)) {
|
|
||||||
type=RESTYP_OUTGOING;
|
type=RESTYP_OUTGOING;
|
||||||
DEBUGC(DBCLASS_PROXY,"outgoing response for %s@%s from inbound",
|
DEBUGC(DBCLASS_PROXY,"outgoing response for %s@%s from inbound",
|
||||||
response->from->url->username,
|
response->from->url->username,
|
||||||
|
|||||||
@ -109,8 +109,7 @@ int register_client(sip_t *my_msg) {
|
|||||||
url2_to=urlmap[i].masq_url;
|
url2_to=urlmap[i].masq_url;
|
||||||
url2_contact=urlmap[i].true_url;
|
url2_contact=urlmap[i].true_url;
|
||||||
|
|
||||||
if ( (strcmp(url1_to->username, url2_to->username )==0) &&
|
if ( (compare_url(url1_to, url2_to)==0) &&
|
||||||
(strcmp(url1_to->host, url2_to->host )==0) &&
|
|
||||||
(strcmp(url1_contact->username, url2_contact->username)==0) &&
|
(strcmp(url1_contact->username, url2_contact->username)==0) &&
|
||||||
(strcmp(url1_contact->host, url2_contact->host )==0) ) {
|
(strcmp(url1_contact->host, url2_contact->host )==0) ) {
|
||||||
DEBUGC(DBCLASS_REG, "found entry for %s@%s at slot=%i, exp=%li",
|
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 */
|
/* listen for incomming messages */
|
||||||
sipsock_listen();
|
sipsock_listen();
|
||||||
|
|
||||||
/*&&&& daemonize !! */
|
/* daemonize if requested to */
|
||||||
if (configuration.daemonize) {
|
if (configuration.daemonize) {
|
||||||
DEBUGC(DBCLASS_CONFIG,"daemonizing");
|
DEBUGC(DBCLASS_CONFIG,"daemonizing");
|
||||||
if (fork()!=0) exit(0);
|
if (fork()!=0) exit(0);
|
||||||
@ -129,8 +129,6 @@ int main (int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Main loop
|
* 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 check_vialoop (sip_t *my_msg);
|
||||||
int is_via_local (via_t *via);
|
int is_via_local (via_t *via);
|
||||||
int get_ip_by_host(char *hostname, struct in_addr *addr);
|
int get_ip_by_host(char *hostname, struct in_addr *addr);
|
||||||
|
int compare_url(url_t *url1, url_t *url2);
|
||||||
|
|
||||||
/* config.c */
|
/* config.c */
|
||||||
int read_config(char *name, int search);
|
int read_config(char *name, int search);
|
||||||
@ -77,20 +78,23 @@ struct siproxd_config {
|
|||||||
/*
|
/*
|
||||||
* some constant definitions
|
* 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 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
|
/* 14-Aug-2002 TR
|
||||||
Linphone puts in the proxies hostname in the request URI when
|
Linphone puts in the proxies hostname in the request URI when
|
||||||
OUTBOUND proxy is activated. But ONLY the hostname. Username and
|
OUTBOUND proxy is activated. But ONLY the hostname. Username and
|
||||||
Port (!!!) are kept from the SIP address givven by the user.
|
Port (!!!) are kept from the SIP address given by the user.
|
||||||
This is a BUG in my eyes. Linphone must send the datagrap to
|
This issue is fixed in linphone-0.9.1pre1
|
||||||
the Proxy, but have the final receiver in the request URI !
|
|
||||||
*/
|
*/
|
||||||
|
|||||||
113
src/utils.c
113
src/utils.c
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
@ -41,6 +42,9 @@ extern struct siproxd_config configuration;
|
|||||||
|
|
||||||
extern int h_errno;
|
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 *msg_make_template_reply (sip_t * request, int code) {
|
||||||
sip_t *response;
|
sip_t *response;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
@ -48,8 +52,8 @@ sip_t *msg_make_template_reply (sip_t * request, int code) {
|
|||||||
|
|
||||||
msg_init (&response);
|
msg_init (&response);
|
||||||
msg_setversion (response, sgetcopy ("SIP/2.0"));
|
msg_setversion (response, sgetcopy ("SIP/2.0"));
|
||||||
tmp = malloc(5);
|
tmp = malloc(STATUSCODE_SIZE);
|
||||||
snprintf (tmp, 5, "%i", code);
|
snprintf (tmp, STATUSCODE_SIZE, "%i", code);
|
||||||
msg_setstatuscode (response, tmp);
|
msg_setstatuscode (response, tmp);
|
||||||
msg_setreasonphrase (response, msg_getreason (code));
|
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 check_vialoop (sip_t *my_msg) {
|
||||||
int sts;
|
int sts;
|
||||||
int pos;
|
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 is_via_local (via_t *via) {
|
||||||
int sts;
|
int sts;
|
||||||
struct in_addr addr_via, addr_myself;
|
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);
|
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;
|
sts=0;
|
||||||
for (i=0; ; i++) {
|
for (i=0; ; i++) {
|
||||||
ptr=my_hostnames[i];
|
ptr=my_hostnames[i];
|
||||||
@ -131,11 +140,52 @@ the via entries !
|
|||||||
return sts;
|
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);
|
hostentry=gethostbyname(hostname);
|
||||||
|
|
||||||
if (hostentry==NULL) {
|
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));
|
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;
|
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