2018-08-11 20:27:14 -05:00
|
|
|
// SPDX-License-Identifier: AGPL-1.0-only
|
|
|
|
// Copyright (C) 2018 Ludvig Strigeus <info@tunsafe.com>. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "tunsafe_types.h"
|
|
|
|
#include <vector>
|
|
|
|
|
2018-09-10 15:53:46 -05:00
|
|
|
class RoutingTrie32 {
|
|
|
|
friend class FreeableNodeCollector;
|
|
|
|
public:
|
|
|
|
typedef void *Value;
|
|
|
|
struct Node;
|
|
|
|
|
|
|
|
RoutingTrie32();
|
|
|
|
~RoutingTrie32();
|
|
|
|
NOINLINE Value Lookup(uint32 ip);
|
|
|
|
NOINLINE Value LookupExact(uint32 ip, int cidr);
|
2018-09-15 11:22:05 -05:00
|
|
|
bool Insert(uint32 ip, int cidr, Value *value);
|
2018-09-10 15:53:46 -05:00
|
|
|
bool Delete(uint32 ip, int cidr);
|
|
|
|
|
|
|
|
private:
|
|
|
|
Node *root_;
|
|
|
|
|
|
|
|
void Rebalance(Node *n);
|
|
|
|
bool Resize(Node *n);
|
|
|
|
bool Inflate(Node **n);
|
|
|
|
bool Halve(Node **n);
|
|
|
|
void UpdateParent(Node *n);
|
|
|
|
void ResizeChildren(Node *n);
|
|
|
|
static void Collapse(Node **n);
|
|
|
|
static void PutChild(Node *pn, uint32 i, Node *n);
|
|
|
|
static void ReplaceChild(Node **pnp, Node *n);
|
|
|
|
static Node *ConvertOleafToLeaf(Node *pn, uint32 i, Node *n);
|
2018-09-15 11:22:05 -05:00
|
|
|
static bool InsertLeafInto(Node **n, uint8 leaf_pos, RoutingTrie32::Value *value);
|
2018-09-10 15:53:46 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2018-08-11 20:27:14 -05:00
|
|
|
// Maps CIDR addresses to a peer, always returning the longest match
|
2018-09-10 15:53:46 -05:00
|
|
|
// IPv6 has a slow O(n) implementation
|
2018-08-11 20:27:14 -05:00
|
|
|
class IpToPeerMap {
|
|
|
|
public:
|
|
|
|
IpToPeerMap();
|
|
|
|
~IpToPeerMap();
|
|
|
|
|
|
|
|
// Inserts an IP address of a given CIDR length into the lookup table, pointing to peer.
|
2018-09-15 11:22:05 -05:00
|
|
|
void *InsertV4(uint32 ip, int cidr, void *peer);
|
|
|
|
void *InsertV6(const void *addr, int cidr, void *peer);
|
2018-08-11 20:27:14 -05:00
|
|
|
|
|
|
|
// Lookup the peer matching the IP Address
|
|
|
|
void *LookupV4(uint32 ip);
|
|
|
|
void *LookupV6(const void *addr);
|
|
|
|
|
|
|
|
void *LookupV4DefaultPeer();
|
|
|
|
void *LookupV6DefaultPeer();
|
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
void RemoveV4(uint32 ip, int cidr);
|
|
|
|
void RemoveV6(const void *addr, int cidr);
|
2018-08-11 20:27:14 -05:00
|
|
|
private:
|
|
|
|
struct Entry6 {
|
|
|
|
uint8 ip[16];
|
|
|
|
uint8 cidr_len;
|
|
|
|
void *peer;
|
|
|
|
};
|
|
|
|
std::vector<Entry6> ipv6_;
|
2018-09-10 15:53:46 -05:00
|
|
|
|
|
|
|
RoutingTrie32 ipv4_;
|
2018-08-11 20:27:14 -05:00
|
|
|
};
|