2002-06-27 00:45:49 +02:00
|
|
|
/**
|
|
|
|
* routers.c
|
|
|
|
* Routines for loading the list of routers and their public RSA keys.
|
|
|
|
*
|
|
|
|
* Matej Pfajfar <mp292@cam.ac.uk>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define OR_ROUTERLIST_SEPCHARS " \t\n"
|
|
|
|
#define OR_PUBLICKEY_BEGIN_TAG "-----BEGIN RSA PUBLIC KEY-----\n"
|
|
|
|
|
|
|
|
#include "or.h"
|
|
|
|
|
2002-07-10 14:35:59 +02:00
|
|
|
/* private function, to determine whether the current entry in the router list is actually us */
|
|
|
|
static int routers_is_us(uint32_t or_address, uint16_t or_listenport, uint16_t my_or_listenport)
|
|
|
|
{
|
|
|
|
/* local host information */
|
|
|
|
char localhostname[512];
|
|
|
|
struct hostent *localhost;
|
|
|
|
|
|
|
|
char *addr = NULL;
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
/* obtain local host information */
|
|
|
|
if (gethostname(localhostname,512) < 0) {
|
|
|
|
log(LOG_ERR,"Error obtaining local hostname.");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
localhost = gethostbyname(localhostname);
|
|
|
|
if (!localhost) {
|
|
|
|
log(LOG_ERR,"Error obtaining local host info.");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check host addresses for a match with or_address above */
|
|
|
|
addr = localhost->h_addr_list[i++]; /* set to the first local address */
|
|
|
|
while(addr)
|
|
|
|
{
|
|
|
|
if (!memcmp((void *)&or_address, (void *)addr, sizeof(uint32_t))) { /* addresses match */
|
|
|
|
if (or_listenport == htons(my_or_listenport)) /* ports also match */
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
addr = localhost->h_addr_list[i++];
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-06-27 00:45:49 +02:00
|
|
|
/* delete a list of routers from memory */
|
|
|
|
void delete_routerlist(routerinfo_t *list)
|
|
|
|
{
|
|
|
|
routerinfo_t *tmp = NULL;
|
|
|
|
|
|
|
|
if (!list)
|
|
|
|
return;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
tmp=list->next;
|
|
|
|
free((void *)list->address);
|
|
|
|
RSA_free(list->pkey);
|
|
|
|
free((void *)list);
|
|
|
|
list = tmp;
|
|
|
|
}
|
|
|
|
while (list != NULL);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* create an NULL-terminated array of pointers pointing to elements of a router list */
|
|
|
|
/* this is done in two passes through the list - inefficient but irrelevant as this is
|
|
|
|
* only done once when op/or start up */
|
|
|
|
routerinfo_t **make_rarray(routerinfo_t* list, size_t *len)
|
|
|
|
{
|
|
|
|
routerinfo_t *tmp=NULL;
|
|
|
|
int listlen = 0;
|
|
|
|
routerinfo_t **array=NULL;
|
|
|
|
routerinfo_t **p=NULL;
|
|
|
|
|
|
|
|
if ((!list) || (!len))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* get the length of the list */
|
|
|
|
tmp = list;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
listlen++;
|
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
|
|
|
while (tmp != NULL);
|
|
|
|
|
|
|
|
array = malloc((listlen+1)*sizeof(routerinfo_t *));
|
|
|
|
if (!array)
|
|
|
|
{
|
|
|
|
log(LOG_ERR,"Error allocating memory.");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmp=list;
|
|
|
|
p = array;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
*p = tmp;
|
|
|
|
p++;
|
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
|
|
|
while(tmp != NULL);
|
|
|
|
*p=NULL;
|
|
|
|
|
|
|
|
*len = listlen;
|
|
|
|
return array;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* load the router list */
|
2002-07-10 14:35:59 +02:00
|
|
|
routerinfo_t **getrouters(char *routerfile, size_t *lenp, uint16_t or_listenport)
|
2002-06-27 00:45:49 +02:00
|
|
|
{
|
|
|
|
int retval = 0;
|
|
|
|
char *retp = NULL;
|
|
|
|
routerinfo_t *router=NULL, *routerlist=NULL, *lastrouter=NULL;
|
|
|
|
FILE *rf; /* router file */
|
|
|
|
fpos_t fpos;
|
|
|
|
char line[512];
|
|
|
|
char *token;
|
|
|
|
char *errtest; /* detecting errors in strtoul() calls */
|
|
|
|
struct hostent *rent;
|
|
|
|
|
|
|
|
if ((!routerfile) || (!lenp))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (strcspn(routerfile,CONFIG_LEGAL_FILENAME_CHARACTERS) != 0)
|
|
|
|
{
|
|
|
|
log(LOG_ERR,"Filename %s contains illegal characters.",routerfile);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* open the router list */
|
|
|
|
rf = fopen(routerfile,"r");
|
|
|
|
if (!rf)
|
|
|
|
{
|
|
|
|
log(LOG_ERR,"Could not open %s.",routerfile);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
retp= fgets(line,512,rf);
|
|
|
|
while (retp)
|
|
|
|
{
|
|
|
|
log(LOG_DEBUG,"getrouters():Line :%s",line);
|
|
|
|
token = (char *)strtok(line,OR_ROUTERLIST_SEPCHARS);
|
|
|
|
if (token)
|
|
|
|
{
|
|
|
|
log(LOG_DEBUG,"getrouters():Token : %s",token);
|
|
|
|
if (token[0] != '#') /* ignore comment lines */
|
|
|
|
{
|
|
|
|
router = malloc(sizeof(routerinfo_t));
|
|
|
|
if (!router)
|
|
|
|
{
|
|
|
|
log(LOG_ERR,"Could not allocate memory.");
|
|
|
|
fclose(rf);
|
|
|
|
delete_routerlist(routerlist);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
router->conn_bufs = NULL; /* no output buffers */
|
|
|
|
router->last_conn_buf = NULL;
|
|
|
|
router->next_to_service = 0;
|
|
|
|
|
|
|
|
router->s = -1; /* to signify this router is as yet unconnected */
|
|
|
|
router->celllen = 0; /* cell buffer is empty */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* read the address */
|
|
|
|
router->address = malloc(strlen(token)+1);
|
|
|
|
if (!router->address)
|
|
|
|
{
|
|
|
|
log(LOG_ERR,"Could not allocate memory.");
|
|
|
|
fclose(rf);
|
|
|
|
free((void *)router);
|
|
|
|
delete_routerlist(routerlist);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
strcpy(router->address,token);
|
|
|
|
|
|
|
|
rent = (struct hostent *)gethostbyname(router->address);
|
|
|
|
if (!rent)
|
|
|
|
{
|
|
|
|
log(LOG_ERR,"Could not get address for router %s.",router->address);
|
|
|
|
fclose(rf);
|
|
|
|
free((void *)router->address);
|
|
|
|
free((void *)router);
|
|
|
|
delete_routerlist(routerlist);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(&router->addr, rent->h_addr,rent->h_length);
|
|
|
|
|
|
|
|
/* read the port */
|
|
|
|
token = (char *)strtok(NULL,OR_ROUTERLIST_SEPCHARS);
|
|
|
|
if (token)
|
|
|
|
{
|
|
|
|
log(LOG_DEBUG,"getrouters():Token :%s",token);
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
router->or_port = (uint16_t)strtoul(token,&errtest,0);
|
2002-06-27 00:45:49 +02:00
|
|
|
if ((*token != '\0') && (*errtest == '\0')) /* conversion was successful */
|
|
|
|
{
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
/* FIXME patch from RD. We should make it actually read these. */
|
2002-07-10 14:35:59 +02:00
|
|
|
router->op_port = htons(router->or_port + 10);
|
|
|
|
router->ap_port = htons(router->or_port + 20);
|
2002-06-27 00:45:49 +02:00
|
|
|
/* convert port to network format */
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
router->or_port = htons(router->or_port);
|
2002-06-27 00:45:49 +02:00
|
|
|
|
|
|
|
/* read min bandwidth */
|
|
|
|
token = (char *)strtok(NULL,OR_ROUTERLIST_SEPCHARS);
|
|
|
|
if (token) /* min bandwidth */
|
|
|
|
{
|
|
|
|
router->min = (uint32_t)strtoul(token,&errtest,0);
|
|
|
|
if ((*token != '\0') && (*errtest == '\0')) /* conversion was successful */
|
|
|
|
{
|
|
|
|
if (router->min) /* must not be zero */
|
|
|
|
{
|
|
|
|
/* read max bandwidth */
|
|
|
|
token = (char *)strtok(NULL,OR_ROUTERLIST_SEPCHARS);
|
|
|
|
if (token) /* max bandwidth */
|
|
|
|
{
|
|
|
|
router->max = (uint32_t)strtoul(token,&errtest,0);
|
|
|
|
if ((*token != '\0') && (*errtest == '\0')) /* conversion was successful */
|
|
|
|
{
|
|
|
|
if (router->max) /* must not be zero */
|
|
|
|
{
|
|
|
|
/* check that there is a public key entry for that router */
|
|
|
|
retval = fgetpos(rf, &fpos); /* save the current file position
|
|
|
|
* we wil return to it later if we find a public key */
|
|
|
|
if (retval == -1)
|
|
|
|
{
|
|
|
|
log(LOG_ERR,"Could not save position in %s.",routerfile);
|
|
|
|
free((void *)router->address);
|
|
|
|
free((void *)router);
|
|
|
|
fclose(rf);
|
|
|
|
delete_routerlist(routerlist);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
do /* read through to the next non-empty line */
|
|
|
|
{
|
|
|
|
retp=fgets(line,512,rf);
|
|
|
|
if (!retp)
|
|
|
|
{
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
log(LOG_ERR,"Could not find a public key entry for router %s:%u.",
|
2002-07-10 14:35:59 +02:00
|
|
|
router->address,router->or_port);
|
2002-06-27 00:45:49 +02:00
|
|
|
free((void *)router->address);
|
|
|
|
free((void *)router);
|
|
|
|
fclose(rf);
|
|
|
|
delete_routerlist(routerlist);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
log(LOG_DEBUG,"getrouters():Line:%s",line);
|
|
|
|
if ((*line != '#') && ( strspn(line,OR_ROUTERLIST_SEPCHARS) != strlen(line) ))
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while (1);
|
|
|
|
|
|
|
|
if (!strcmp(line,OR_PUBLICKEY_BEGIN_TAG)) /* we've got the public key */
|
|
|
|
{
|
|
|
|
retval = fsetpos(rf,&fpos); /* get us back to where we were otherwise crypto lib won't find the key */
|
|
|
|
if (retval == -1)
|
|
|
|
{
|
|
|
|
log(LOG_ERR,"Could not set position in %s.",routerfile);
|
|
|
|
free((void *)router->address);
|
|
|
|
free((void *)router);
|
|
|
|
fclose(rf);
|
|
|
|
delete_routerlist(routerlist);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else /* we found something else; this isn't right */
|
|
|
|
{
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
log(LOG_ERR,"Could not find a public key entry for router %s:%u.",
|
|
|
|
router->address,router->or_port);
|
2002-06-27 00:45:49 +02:00
|
|
|
free((void *)router->address);
|
|
|
|
free((void *)router);
|
|
|
|
fclose(rf);
|
|
|
|
delete_routerlist(routerlist);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
log(LOG_DEBUG,"getrouters():Reading the key ...");
|
|
|
|
/* read the public key into router->pkey */
|
|
|
|
router->pkey=NULL;
|
|
|
|
router->pkey = PEM_read_RSAPublicKey(rf,&router->pkey,NULL,NULL);
|
|
|
|
if (!router->pkey) /* something went wrong */
|
|
|
|
{
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
log(LOG_ERR,"Could not read public key for router %s:%u.",
|
|
|
|
router->address,router->or_port);
|
2002-06-27 00:45:49 +02:00
|
|
|
free((void *)router->address);
|
|
|
|
free((void *)router);
|
|
|
|
fclose(rf);
|
|
|
|
delete_routerlist(routerlist);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
else /* read the key */
|
|
|
|
{
|
|
|
|
log(LOG_DEBUG,"getrouters():Public key size = %u.", RSA_size(router->pkey));
|
|
|
|
if (RSA_size(router->pkey) != 128) /* keys MUST be 1024 bits in size */
|
|
|
|
{
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
log(LOG_ERR,"Key for router %s:%u is not 1024 bits. All keys must be exactly 1024 bits long.",router->address,router->or_port);
|
2002-06-27 00:45:49 +02:00
|
|
|
free((void *)router->address);
|
|
|
|
RSA_free(router->pkey);
|
|
|
|
free((void *)router);
|
|
|
|
fclose(rf);
|
|
|
|
delete_routerlist(routerlist);
|
|
|
|
return NULL;
|
|
|
|
}
|
2002-07-10 14:35:59 +02:00
|
|
|
|
|
|
|
/* check that this router doesn't actually represent us */
|
|
|
|
retval = routers_is_us(router->addr, router->or_port, or_listenport);
|
|
|
|
if (!retval) { /* this isn't us, continue */
|
|
|
|
router->next = NULL;
|
|
|
|
/* save the entry into the routerlist linked list */
|
|
|
|
if (!routerlist) /* this is the first entry */
|
|
|
|
routerlist = router;
|
|
|
|
else
|
|
|
|
lastrouter->next = (void *)router;
|
|
|
|
lastrouter = router;
|
|
|
|
}
|
|
|
|
else if (retval == 1) /* this is us, ignore */
|
|
|
|
{
|
|
|
|
log(LOG_DEBUG,"getrouters(): This entry is actually me. Ignoring.");
|
|
|
|
free((void *)router->address);
|
|
|
|
RSA_free(router->pkey);
|
|
|
|
free((void *)router);
|
|
|
|
}
|
|
|
|
else /* routers_is_us() returned an error */
|
|
|
|
{
|
|
|
|
free((void *)router->address);
|
|
|
|
RSA_free(router->pkey);
|
|
|
|
free((void *)router);
|
|
|
|
fclose(rf);
|
|
|
|
delete_routerlist(routerlist);
|
|
|
|
return NULL;
|
|
|
|
}
|
2002-06-27 00:45:49 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else /* maximum link utilisation is zero */
|
|
|
|
{
|
|
|
|
log(LOG_ERR,"Entry for router %s doesn't contain a valid maximum bandwidth entry (must be > 0).",router->address);
|
|
|
|
free((void *)router->address);
|
|
|
|
free((void *)router);
|
|
|
|
fclose(rf);
|
|
|
|
delete_routerlist(routerlist);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
log(LOG_ERR,"Entry for router %s doesn't seem to contain a valid maximum bandwidth entry.",router->address);
|
|
|
|
free((void *)router->address);
|
|
|
|
free((void *)router);
|
|
|
|
fclose(rf);
|
|
|
|
delete_routerlist(routerlist);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
log(LOG_ERR,"Entry for router %s doesn't seem to contain a maximum bandwidth entry.",router->address);
|
|
|
|
free((void *)router->address);
|
|
|
|
free((void *)router);
|
|
|
|
fclose(rf);
|
|
|
|
delete_routerlist(routerlist);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
log(LOG_ERR,"Entry for router %s doesn't contain a valid minimum bandwidth entry (must be > 0).",router->address);
|
|
|
|
free((void *)router->address);
|
|
|
|
free((void *)router);
|
|
|
|
fclose(rf);
|
|
|
|
delete_routerlist(routerlist);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
log(LOG_ERR,"Entry for router %s doesn't seem to contain a valid minimum bandwidth entry.",router->address);
|
|
|
|
free((void *)router->address);
|
|
|
|
free((void *)router);
|
|
|
|
fclose(rf);
|
|
|
|
delete_routerlist(routerlist);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
log(LOG_ERR,"Entry for router %s doesn't seem to contain a minimum bandwidth entry.",router->address);
|
|
|
|
free((void *)router->address);
|
|
|
|
free((void *)router);
|
|
|
|
fclose(rf);
|
|
|
|
delete_routerlist(routerlist);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
log(LOG_ERR,"Entry for router %s doesn't seem to contain a valid port number.",router->address);
|
|
|
|
free((void *)router->address);
|
|
|
|
free((void *)router);
|
|
|
|
fclose(rf);
|
|
|
|
delete_routerlist(routerlist);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
log(LOG_ERR,"Entry for router %s doesn't seem to contain a port number.",router->address);
|
|
|
|
free((void *)router->address);
|
|
|
|
free((void *)router);
|
|
|
|
fclose(rf);
|
|
|
|
delete_routerlist(routerlist);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
retp=fgets(line,512,rf);
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose(rf);
|
|
|
|
return make_rarray(routerlist, lenp);
|
|
|
|
}
|