mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-01-07 09:31:54 +00:00
4661035431
The RPKI protocol (RFC 6810) using the RTRLib (http://rpki.realmv6.org/) that is integrated inside the BIRD's code. Implemeted transports are: - unprotected transport over TCP - secure transport over SSHv2 Example configuration of bird.conf: ... roa4 table r4; roa6 table r6; protocol rpki { debug all; # Import both IPv4 and IPv6 ROAs roa4 { table r4; }; roa6 { table r6; }; # Set cache server (validator) address, # overwrite default port 323 remote "rpki-validator.realmv6.org" port 8282; # Overwrite default time intervals retry 10; # Default 600 seconds refresh 60; # Default 3600 seconds expire 600; # Default 7200 seconds } protocol rpki { debug all; # Import only IPv4 routes roa4 { table r4; }; # Set cache server address to localhost, # use default ports tcp => 323 or ssh => 22 remote 127.0.0.1; # Use SSH transport instead of unprotected transport over TCP ssh encryption { bird private key "/home/birdgeek/.ssh/id_rsa"; remote public key "/home/birdgeek/.ssh/known_hosts"; user "birdgeek"; }; } ...
110 lines
2.4 KiB
C
110 lines
2.4 KiB
C
/*
|
|
* BIRD -- The Resource Public Key Infrastructure (RPKI) to Router Protocol
|
|
*
|
|
* (c) 2015 CZ.NIC
|
|
*
|
|
* This file was a part of RTRlib: http://rpki.realmv6.org/
|
|
*
|
|
* Can be freely distributed and used under the terms of the GNU GPL.
|
|
*/
|
|
|
|
#include <sys/socket.h>
|
|
#include <netdb.h>
|
|
|
|
#include "rpki.h"
|
|
#include "transport.h"
|
|
#include "sysdep/unix/unix.h"
|
|
|
|
/*
|
|
* Fulfill sock->af and sock->daddr if sock->daddr is empty and hostname is defined
|
|
* Return TR_SUCCESS or TR_ERROR
|
|
*/
|
|
static int
|
|
rpki_hostname_autoresolv(sock *sk)
|
|
{
|
|
if (ipa_zero(sk->daddr) && sk->host)
|
|
{
|
|
struct addrinfo *res;
|
|
struct addrinfo hints = {
|
|
.ai_family = AF_UNSPEC,
|
|
.ai_socktype = SOCK_STREAM,
|
|
.ai_flags = AI_ADDRCONFIG,
|
|
};
|
|
|
|
char port[6]; /* max is "65535" + '\0' */
|
|
bsnprintf(port, sizeof(port), "%u", sk->dport);
|
|
|
|
if (getaddrinfo(sk->host, port, &hints, &res) != 0)
|
|
{
|
|
CACHE_TRACE(D_EVENTS, (struct rpki_cache *) sk->data, "getaddrinfo error, %s", gai_strerror(errno));
|
|
return TR_ERROR;
|
|
}
|
|
|
|
if (res->ai_family == AF_INET)
|
|
sk->fam = SK_FAM_IPV4;
|
|
else
|
|
sk->fam = SK_FAM_IPV6;
|
|
|
|
sockaddr sa = {
|
|
.sa = *res->ai_addr,
|
|
};
|
|
|
|
uint unused;
|
|
sockaddr_read(&sa, res->ai_family, &sk->daddr, NULL, &unused);
|
|
|
|
freeaddrinfo(res);
|
|
}
|
|
else if (ipa_zero(sk->daddr) && !sk->host)
|
|
return TR_ERROR;
|
|
else
|
|
sk->fam = ip6_is_v4mapped(sk->daddr) ? SK_FAM_IPV4 : SK_FAM_IPV6;
|
|
|
|
return TR_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
* Establish the connection.
|
|
* Returns TR_SUCCESS or TR_ERROR
|
|
*/
|
|
int
|
|
rpki_tr_open(struct rpki_tr_sock *tr)
|
|
{
|
|
struct rpki_cache *cache = tr->cache;
|
|
struct rpki_config *cf = (void *) cache->p->p.cf;
|
|
|
|
ASSERT(tr->sk == NULL);
|
|
tr->sk = sk_new(cache->pool);
|
|
sock *sk = tr->sk;
|
|
|
|
sk->tx_hook = rpki_connected_hook;
|
|
sk->err_hook = rpki_err_hook;
|
|
sk->data = cache;
|
|
sk->daddr = cf->ip;
|
|
sk->dport = cf->port;
|
|
sk->host = cf->hostname;
|
|
sk->rbsize = RPKI_RX_BUFFER_SIZE;
|
|
sk->tbsize = RPKI_TX_BUFFER_SIZE;
|
|
sk->tos = IP_PREC_INTERNET_CONTROL;
|
|
sk->type = -1; /* must be set in the specific transport layer in tr_open() */
|
|
rpki_hostname_autoresolv(sk);
|
|
|
|
return tr->open_fp(tr);
|
|
}
|
|
|
|
/* Close socket and prepare it for possible next open */
|
|
inline void
|
|
rpki_tr_close(struct rpki_tr_sock *tr)
|
|
{
|
|
tr->close_fp(tr);
|
|
|
|
rfree(tr->sk);
|
|
tr->sk = NULL;
|
|
}
|
|
|
|
/* Returns a \0 terminated string identifier for the socket endpoint, eg host:port */
|
|
inline const char *
|
|
rpki_tr_ident(struct rpki_tr_sock *tr)
|
|
{
|
|
return tr->ident_fp(tr);
|
|
}
|