-/*
- receive incoming data from the listening
- udp socket and write it to the ethertap
- device after being decrypted
-*/
-void handle_incoming_vpn_data(void)
-{
- vpn_packet_t pkt;
- int x, l = sizeof(x);
- int lenin;
- struct sockaddr_in from;
- socklen_t fromlen = sizeof(from);
- connection_t *cl;
-cp
- if(getsockopt(myself->socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0)
- {
- syslog(LOG_ERR, _("This is a bug: %s:%d: %d:%m"),
- __FILE__, __LINE__, myself->socket);
- return;
- }
- if(x)
- {
- syslog(LOG_ERR, _("Incoming data socket error: %s"), strerror(x));
- return;
- }
-
- if((lenin = recvfrom(myself->socket, (char *) &(pkt.len), MTU, 0, (struct sockaddr *)&from, &fromlen)) <= 0)
- {
- syslog(LOG_ERR, _("Receiving packet failed: %m"));
- return;
- }
-
- cl = lookup_connection(ntohl(from.sin_addr.s_addr), ntohs(from.sin_port));
-
- if(!cl)
- {
- syslog(LOG_WARNING, _("Received UDP packets on port %hd from unknown source %x:%hd"), myself->port, ntohl(from.sin_addr.s_addr), ntohs(from.sin_port));
- return;
- }
-
- receive_udppacket(cl, &pkt);
-cp
-}
-
-/*
- terminate a connection and notify the other
- end before closing the sockets
-*/
-void terminate_connection(connection_t *cl)
-{
- connection_t *p;
- subnet_t *subnet;
- avl_node_t *node, *next;
-cp
- if(cl->status.remove)
- return;
-
- if(debug_lvl >= DEBUG_CONNECTIONS)
- syslog(LOG_NOTICE, _("Closing connection with %s (%s)"),
- cl->name, cl->hostname);
-
- cl->status.remove = 1;
-
- if(cl->socket)
- close(cl->socket);
- if(cl->status.meta)
- close(cl->meta_socket);
-
- if(cl->status.meta)
- {
-
- /* Find all connections that were lost because they were behind cl
- (the connection that was dropped). */
-
- for(node = connection_tree->head; node; node = node->next)
- {
- p = (connection_t *)node->data;
- if(p->nexthop == cl && p != cl)
- terminate_connection(p);
- }
-
- /* Inform others of termination if it was still active */
-
- if(cl->status.active)
- for(node = connection_tree->head; node; node = node->next)
- {
- p = (connection_t *)node->data;
- if(p->status.meta && p->status.active && p != cl)
- send_del_host(p, cl); /* Sounds like recursion, but p does not have a meta connection :) */
- }
- }
-
- /* Remove the associated subnets */
-
- for(node = cl->subnet_tree->head; node; node = next)
- {
- next = node->next;
- subnet = (subnet_t *)node->data;
- subnet_del(subnet);
- }
-
- /* Check if this was our outgoing connection */
-
- if(cl->status.outgoing)
- {
- cl->status.outgoing = 0;
- signal(SIGALRM, sigalrm_handler);
- seconds_till_retry = 5;
- alarm(seconds_till_retry);
- syslog(LOG_NOTICE, _("Trying to re-establish outgoing connection in 5 seconds"));
- }
-
- /* Inactivate */
-
- cl->status.active = 0;
-cp