- while((old = lookup_id(cl->name)))
- {
- if(debug_lvl >= DEBUG_CONNECTIONS)
- syslog(LOG_NOTICE, _("Removing old entry for %s at %s in favour of new connection from %s"),
- cl->name, old->hostname, cl->hostname);
-
- terminate_connection(old);
- }
-
- /* Activate this connection */
-
- cl->allow_request = ALL;
- cl->status.active = 1;
- cl->status.decryptin = 1;
- cl->nexthop = cl;
- cl->cipher_pkttype = EVP_bf_cfb();
- cl->cipher_pktkeylength = cl->cipher_pkttype->key_len + cl->cipher_pkttype->iv_len;
-
- if(debug_lvl >= DEBUG_CONNECTIONS)
- syslog(LOG_NOTICE, _("Connection with %s (%s) activated"), cl->name, cl->hostname);
-
-cp
- if(!cl->status.outgoing)
- send_ack(cl);
-
- /* Send him our subnets */
-
- RBL_FOREACH(myself->subnet_tree, rbl)
- {
- subnet = (subnet_t *)rbl->data;
- send_add_subnet(cl, subnet);
- }
- /* And send him all the hosts and their subnets we know... */
-
- RBL_FOREACH(connection_tree, rbl)
- {
- p = (connection_t *)rbl->data;
-
- if(p != cl && p->status.active)
- {
- /* Notify others of this connection */
-
- if(p->status.meta)
- send_add_host(p, cl);
-
- /* Notify new connection of everything we know */
-
- send_add_host(cl, p);
-
- RBL_FOREACH(p->subnet_tree, rbl2)
- {
- subnet = (subnet_t *)rbl2->data;
- send_add_subnet(cl, subnet);
- }
- }
- }
-cp
- return 0;
-}
-
-/* Address and subnet information exchange */
-
-int send_add_subnet(connection_t *cl, subnet_t *subnet)
-{
- int x;
- char *netstr;
-cp
- x = send_request(cl, "%d %s %s", ADD_SUBNET,
- subnet->owner->name, netstr = net2str(subnet));
- free(netstr);
-cp
- return x;
-}
-
-int add_subnet_h(connection_t *cl)
-{
- char subnetstr[MAX_STRING_SIZE];
- char name[MAX_STRING_SIZE];
- connection_t *owner, *p;
- subnet_t *subnet;
- rbl_t *rbl;
-cp
- if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 2)
- {
- syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s)"), cl->name, cl->hostname);
- return -1;
- }
-
- /* Check if owner name is a valid */
-
- if(check_id(name))
- {
- syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s): invalid identity name"), cl->name, cl->hostname);
- return -1;
- }
-
- /* Check if subnet string is valid */
-
- if(!(subnet = str2net(subnetstr)))
- {
- syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s): invalid subnet string"), cl->name, cl->hostname);
- return -1;
- }
-
- /* Check if somebody tries to add a subnet of ourself */
-
- if(!strcmp(name, myself->name))
- {
- syslog(LOG_ERR, _("Warning: got ADD_SUBNET from %s (%s) for ourself, restarting"),
- cl->name, cl->hostname);
- sighup = 1;
- return 0;
- }
-
- /* Check if the owner of the new subnet is in the connection list */
-
- if(!(owner = lookup_id(name)))
- {
- syslog(LOG_ERR, _("Got ADD_SUBNET for %s from %s (%s) which is not in our connection list"),
- name, cl->name, cl->hostname);
- return -1;
- }
-
- /* If everything is correct, add the subnet to the list of the owner */
-
- subnet_add(owner, subnet);
-
- /* Tell the rest */
-
- RBL_FOREACH(connection_tree, rbl)
- {
- p = (connection_t *)rbl->data;
- if(p->status.meta && p->status.active && p!= cl)
- send_add_subnet(p, subnet);
- }
-cp
- return 0;
-}
-
-int send_del_subnet(connection_t *cl, subnet_t *subnet)
-{
- int x;
- char *netstr;
-cp
- netstr = net2str(subnet);
- x = send_request(cl, "%d %s %s", DEL_SUBNET, subnet->owner->name, netstr);
- free(netstr);
-cp
- return x;
-}
-
-int del_subnet_h(connection_t *cl)
-{
- char subnetstr[MAX_STRING_SIZE];
- char name[MAX_STRING_SIZE];
- connection_t *owner, *p;
- subnet_t *subnet;
- rbl_t *rbl;
-cp
- if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 3)
- {
- syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s)"), cl->name, cl->hostname);
- return -1;
- }
-
- /* Check if owner name is a valid */
-
- if(check_id(name))
- {
- syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s): invalid identity name"), cl->name, cl->hostname);
- return -1;
- }
-
- /* Check if subnet string is valid */
-
- if(!(subnet = str2net(subnetstr)))
- {
- syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s): invalid subnet string"), cl->name, cl->hostname);
- return -1;
- }
-
- free(subnetstr);
-
- /* Check if somebody tries to add a subnet of ourself */
-
- if(!strcmp(name, myself->name))
- {
- syslog(LOG_ERR, _("Warning: got DEL_SUBNET from %s (%s) for ourself, restarting"),
- cl->name, cl->hostname);
- sighup = 1;
- return 0;
- }
-
- /* Check if the owner of the new subnet is in the connection list */
-
- if(!(owner = lookup_id(name)))
- {
- syslog(LOG_ERR, _("Got DEL_SUBNET for %s from %s (%s) which is not in our connection list"),
- name, cl->name, cl->hostname);
- return -1;
- }
-
- /* If everything is correct, delete the subnet from the list of the owner */
-
- subnet_del(subnet);
-
- /* Tell the rest */
-
- RBL_FOREACH(connection_tree, rbl)
- {
- p = (connection_t *)rbl->data;
- if(p->status.meta && p->status.active && p!= cl)
- send_del_subnet(p, subnet);
- }
-cp
- return 0;
-}
-
-/* New and closed connections notification */
-
-int send_add_host(connection_t *cl, connection_t *other)
-{
-cp
- return send_request(cl, "%d %s %lx:%d %lx", ADD_HOST,
- other->name, other->address, other->port, other->options);
-}
-
-int add_host_h(connection_t *cl)
-{
- connection_t *old, *new, *p;
- char name[MAX_STRING_SIZE];
- rbl_t *rbl;
-cp
- new = new_connection();
-
- if(sscanf(cl->buffer, "%*d "MAX_STRING" %lx:%d %lx", name, &new->address, &new->port, &new->options) != 4)
- {
- syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s)"), cl->name, cl->hostname);
- return -1;
- }
-
- /* Check if identity is a valid name */
-
- if(check_id(name))
- {
- syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
- free_connection(new);
- return -1;
- }
-
- /* Check if somebody tries to add ourself */
-
- if(!strcmp(new->name, myself->name))
- {
- syslog(LOG_ERR, _("Warning: got ADD_HOST from %s (%s) for ourself, restarting"), cl->name, cl->hostname);
- sighup = 1;
- free_connection(new);
- return 0;
- }
-
- /* Fill in more of the new connection structure */
-
- new->hostname = hostlookup(htonl(new->address));
-
- /* Check if the new host already exists in the connnection list */
-
- if((old = lookup_id(name)))
- {
- if((new->address == old->address) && (new->port == old->port))
- {
- if(debug_lvl >= DEBUG_CONNECTIONS)
- syslog(LOG_NOTICE, _("Got duplicate ADD_HOST for %s (%s) from %s (%s)"),
- old->name, old->hostname, name, new->hostname);
- free_connection(new);
- return 0;
- }
- else
- {
- if(debug_lvl >= DEBUG_CONNECTIONS)
- syslog(LOG_NOTICE, _("Removing old entry for %s (%s) in favour of new connection"),
- old->name, old->hostname);
-
- terminate_connection(old);
- }
- }
-
- /* Hook it up into the connection */
-
- new->name = xstrdup(name);
- connection_add(new);
- id_add(new);
-
- /* Tell the rest about the new host */