- }
-
- /* Decrypt the packet */
-
- if(myself->cipher)
- {
- EVP_DecryptInit(&ctx, myself->cipher, myself->key, myself->key + myself->cipher->key_len);
- EVP_DecryptUpdate(&ctx, (char *)&outpkt.seqno, &outlen, (char *)&inpkt->seqno, inpkt->len);
- EVP_DecryptFinal(&ctx, (char *)&outpkt.seqno + outlen, &outpad);
- outlen += outpad;
- outpkt.len = outlen - sizeof(outpkt.seqno);
- }
- else
- {
- memcpy((char *)&outpkt.seqno, (char *)&inpkt->seqno, inpkt->len);
- outpkt.len = inpkt->len - sizeof(outpkt.seqno);
- }
-
- if (ntohl(outpkt.seqno) <= n->received_seqno)
- {
- syslog(LOG_DEBUG, _("Got late or replayed packet from %s (%s), seqno %d"), n->name, n->hostname, ntohl(*(unsigned int *)&outpkt.seqno));
- return;
- }
-
- n->received_seqno = ntohl(outpkt.seqno);
-
- if(n->received_seqno > MAX_SEQNO)
- keyexpires = 0;
-
- receive_packet(n, &outpkt);
-cp
-}
-
-void receive_tcppacket(connection_t *c, char *buffer, int len)
-{
- vpn_packet_t outpkt;
-cp
- outpkt.len = len;
- memcpy(outpkt.data, buffer, len);
-
- receive_packet(c->node, &outpkt);
-cp
-}
-
-void receive_packet(node_t *n, vpn_packet_t *packet)
-{
-cp
- if(debug_lvl >= DEBUG_TRAFFIC)
- syslog(LOG_DEBUG, _("Received packet of %d bytes from %s (%s)"), packet->len, n->name, n->hostname);
-
- route_incoming(n, packet);
-cp
-}
-
-void send_udppacket(node_t *n, vpn_packet_t *inpkt)
-{
- vpn_packet_t outpkt;
- int outlen, outpad;
- EVP_CIPHER_CTX ctx;
- struct sockaddr_in to;
- socklen_t tolen = sizeof(to);
- vpn_packet_t *copy;
-cp
- if(!n->status.validkey)
- {
- if(debug_lvl >= DEBUG_TRAFFIC)
- syslog(LOG_INFO, _("No valid key known yet for %s (%s), queueing packet"),
- n->name, n->hostname);
-
- /* Since packet is on the stack of handle_tap_input(),
- we have to make a copy of it first. */
-
- copy = xmalloc(sizeof(vpn_packet_t));
- memcpy(copy, inpkt, sizeof(vpn_packet_t));
-
- list_insert_tail(n->queue, copy);
-
- if(!n->status.waitingforkey)
- send_req_key(n->nexthop->connection, myself, n);
- return;
- }
-
- /* Encrypt the packet. */
-
- inpkt->seqno = htonl(++(n->sent_seqno));
-
- if(n->cipher)
- {
- EVP_EncryptInit(&ctx, n->cipher, n->key, n->key + n->cipher->key_len);
- EVP_EncryptUpdate(&ctx, (char *)&outpkt.seqno, &outlen, (char *)&inpkt->seqno, inpkt->len + sizeof(inpkt->seqno));
- EVP_EncryptFinal(&ctx, (char *)&outpkt.seqno + outlen, &outpad);
- outlen += outpad;
- }
- else
- {
- memcpy((char *)&outpkt.seqno, (char *)&inpkt->seqno, inpkt->len + sizeof(inpkt->seqno));
- outlen = inpkt->len + sizeof(inpkt->seqno);
- }
-
- if(n->digest && n->maclength)
- {
- HMAC(n->digest, n->key, n->keylength, (char *)&outpkt.seqno, outlen, (char *)&outpkt.seqno + outlen, &outpad);
- outlen += n->maclength;
- }
-
- to.sin_family = AF_INET;
- to.sin_addr.s_addr = htonl(n->address);
- to.sin_port = htons(n->port);
-
- if((sendto(udp_socket, (char *)&outpkt.seqno, outlen, 0, (const struct sockaddr *)&to, tolen)) < 0)
- {
- syslog(LOG_ERR, _("Error sending packet to %s (%s): %m"),
- n->name, n->hostname);
- return;
- }
-cp