Include complete fake-getname/addrinfo from OpenSSH.

This commit is contained in:
Guus Sliepen 2002-07-12 11:45:21 +00:00
parent afabbd6b90
commit c4cd199357
12 changed files with 242 additions and 711 deletions

View file

@ -1,6 +1,6 @@
dnl Process this file with autoconf to produce a configure script.
dnl $Id: configure.in,v 1.13.2.52 2002/07/11 12:55:57 guus Exp $
dnl $Id: configure.in,v 1.13.2.53 2002/07/12 11:45:20 guus Exp $
AC_INIT(src/tincd.c)
AM_INIT_AUTOMAKE(tinc, 1.0-cvs)
@ -105,12 +105,27 @@ if test $ac_cv_type_socklen_t = yes; then
AC_DEFINE(HAVE_SOCKLEN_T, 1, [socklen_t available])
fi
AC_CACHE_CHECK([for struct addrinfo], ac_cv_struct_addrinfo,
[
AC_TRY_COMPILE(
[#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>],
[struct addrinfo ai; ai.ai_family = AF_INET; return ai.ai_family;],
ac_cv_struct_addrinfo=yes,
ac_cv_struct_addrinfo=no)
])
if test $ac_cv_struct_addrinfo = yes; then
AC_DEFINE(HAVE_STRUCT_ADDRINFO, 1, [struct addrinfo available])
fi
dnl Checks for library functions.
AC_FUNC_MEMCMP
AC_FUNC_ALLOCA
AC_TYPE_SIGNAL
AC_CHECK_FUNCS([asprintf daemon fcloseall flock ftime get_current_dir_name \
putenv select strdup strerror strsignal strtol unsetenv getnameinfo])
putenv select strdup strerror strsignal strtol unsetenv \
freeaddrinfo gai_strerror getaddrinfo getnameinfo])
jm_FUNC_MALLOC
jm_FUNC_REALLOC

View file

@ -1,15 +1,15 @@
## Process this file with automake to produce Makefile.in
# $Id: Makefile.am,v 1.2.4.8 2002/06/09 15:50:11 zarq Exp $
# $Id: Makefile.am,v 1.2.4.9 2002/07/12 11:45:21 guus Exp $
noinst_LIBRARIES = libvpn.a
INCLUDES = @INCLUDES@ -I. -I$(top_builddir) -I$(top_srcdir)/intl
libvpn_a_SOURCES = xmalloc.c pidfile.c utils.c getopt.c getopt1.c list.c avl_tree.c dropin.c
libvpn_a_SOURCES = xmalloc.c pidfile.c utils.c getopt.c getopt1.c list.c avl_tree.c dropin.c fake-getaddrinfo.c fake-getnameinfo.c
libvpn_a_LIBADD = @LIBOBJS@ @ALLOCA@
libvpn_a_DEPENDENCIES = $(libvpn_a_LIBADD)
noinst_HEADERS = xalloc.h pidfile.h utils.h getopt.h list.h avl_tree.h dropin.h
noinst_HEADERS = xalloc.h pidfile.h utils.h getopt.h list.h avl_tree.h dropin.h fake-getaddrinfo.h fake-getnameinfo.h
EXTRA_DIST = README fake-getnameinfo.c
EXTRA_DIST =

View file

@ -1 +0,0 @@
The files in this directory were merely copied from fileutils 4.0.

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: dropin.c,v 1.1.2.10 2002/06/21 10:11:11 guus Exp $
$Id: dropin.c,v 1.1.2.11 2002/07/12 11:45:21 guus Exp $
*/
#include "config.h"
@ -35,8 +35,6 @@
#include <system.h>
#include <errno.h>
#include "fake-getnameinfo.c"
#ifndef HAVE_DAEMON
/*
Replacement for the daemon() function.

14
lib/fake-gai-errnos.h Normal file
View file

@ -0,0 +1,14 @@
/*
* fake library for ssh
*
* This file is included in getaddrinfo.c and getnameinfo.c.
* See getaddrinfo.c and getnameinfo.c.
*/
/* $Id: fake-gai-errnos.h,v 1.1.2.1 2002/07/12 11:45:21 guus Exp $ */
/* for old netdb.h */
#ifndef EAI_NODATA
#define EAI_NODATA 1
#define EAI_MEMORY 2
#endif

128
lib/fake-getaddrinfo.c Normal file
View file

@ -0,0 +1,128 @@
/*
* fake library for ssh
*
* This file includes getaddrinfo(), freeaddrinfo() and gai_strerror().
* These funtions are defined in rfc2133.
*
* But these functions are not implemented correctly. The minimum subset
* is implemented for ssh use only. For exapmle, this routine assumes
* that ai_family is AF_INET. Don't use it for another purpose.
*/
#include "config.h"
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <system.h>
#include "fake-getaddrinfo.h"
#ifndef HAVE_GAI_STRERROR
char *gai_strerror(int ecode)
{
switch (ecode) {
case EAI_NODATA:
return "no address associated with hostname.";
case EAI_MEMORY:
return "memory allocation failure.";
default:
return "unknown error.";
}
}
#endif /* !HAVE_GAI_STRERROR */
#ifndef HAVE_FREEADDRINFO
void freeaddrinfo(struct addrinfo *ai)
{
struct addrinfo *next;
do {
next = ai->ai_next;
free(ai);
} while (NULL != (ai = next));
}
#endif /* !HAVE_FREEADDRINFO */
#ifndef HAVE_GETADDRINFO
static struct addrinfo *malloc_ai(int port, u_long addr)
{
struct addrinfo *ai;
ai = malloc(sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
if (ai == NULL)
return(NULL);
memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
ai->ai_addr = (struct sockaddr *)(ai + 1);
/* XXX -- ssh doesn't use sa_len */
ai->ai_addrlen = sizeof(struct sockaddr_in);
ai->ai_addr->sa_family = ai->ai_family = AF_INET;
((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;
((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
return(ai);
}
int getaddrinfo(const char *hostname, const char *servname,
const struct addrinfo *hints, struct addrinfo **res)
{
struct addrinfo *cur, *prev = NULL;
struct hostent *hp;
struct in_addr in;
int i, port;
if (servname)
port = htons(atoi(servname));
else
port = 0;
if (hints && hints->ai_flags & AI_PASSIVE) {
if (NULL != (*res = malloc_ai(port, htonl(0x00000000))))
return 0;
else
return EAI_MEMORY;
}
if (!hostname) {
if (NULL != (*res = malloc_ai(port, htonl(0x7f000001))))
return 0;
else
return EAI_MEMORY;
}
if (inet_aton(hostname, &in)) {
if (NULL != (*res = malloc_ai(port, in.s_addr)))
return 0;
else
return EAI_MEMORY;
}
hp = gethostbyname(hostname);
if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
for (i = 0; hp->h_addr_list[i]; i++) {
cur = malloc_ai(port, ((struct in_addr *)hp->h_addr_list[i])->s_addr);
if (cur == NULL) {
if (*res)
freeaddrinfo(*res);
return EAI_MEMORY;
}
if (prev)
prev->ai_next = cur;
else
*res = cur;
prev = cur;
}
return 0;
}
return EAI_NODATA;
}
#endif /* !HAVE_GETADDRINFO */

51
lib/fake-getaddrinfo.h Normal file
View file

@ -0,0 +1,51 @@
/* $Id: fake-getaddrinfo.h,v 1.1.2.1 2002/07/12 11:45:21 guus Exp $ */
#ifndef _FAKE_GETADDRINFO_H
#define _FAKE_GETADDRINFO_H
#include "config.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include "fake-gai-errnos.h"
#ifndef AI_PASSIVE
# define AI_PASSIVE 1
# define AI_CANONNAME 2
#endif
#ifndef NI_NUMERICHOST
# define NI_NUMERICHOST 2
# define NI_NAMEREQD 4
# define NI_NUMERICSERV 8
#endif
#ifndef HAVE_STRUCT_ADDRINFO
struct addrinfo {
int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
int ai_family; /* PF_xxx */
int ai_socktype; /* SOCK_xxx */
int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
size_t ai_addrlen; /* length of ai_addr */
char *ai_canonname; /* canonical name for hostname */
struct sockaddr *ai_addr; /* binary address */
struct addrinfo *ai_next; /* next structure in linked list */
};
#endif /* !HAVE_STRUCT_ADDRINFO */
#ifndef HAVE_GETADDRINFO
int getaddrinfo(const char *hostname, const char *servname,
const struct addrinfo *hints, struct addrinfo **res);
#endif /* !HAVE_GETADDRINFO */
#ifndef HAVE_GAI_STRERROR
char *gai_strerror(int ecode);
#endif /* !HAVE_GAI_STRERROR */
#ifndef HAVE_FREEADDRINFO
void freeaddrinfo(struct addrinfo *ai);
#endif /* !HAVE_FREEADDRINFO */
#endif /* _FAKE_GETADDRINFO_H */

View file

@ -19,7 +19,7 @@
#include <system.h>
/* RCSID("$Id: fake-getnameinfo.c,v 1.1.2.3 2002/06/09 16:12:04 zarq Exp $"); */
#include "fake-getnameinfo.h"
#ifndef HAVE_GETNAMEINFO

23
lib/fake-getnameinfo.h Normal file
View file

@ -0,0 +1,23 @@
/* $Id: fake-getnameinfo.h,v 1.1.2.1 2002/07/12 11:45:21 guus Exp $ */
#ifndef _FAKE_GETNAMEINFO_H
#define _FAKE_GETNAMEINFO_H
#include "config.h"
#include <sys/socket.h>
#include <netdb.h>
#ifndef HAVE_GETNAMEINFO
int getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
size_t hostlen, char *serv, size_t servlen, int flags);
#endif /* !HAVE_GETNAMEINFO */
#ifndef NI_MAXSERV
# define NI_MAXSERV 32
#endif /* !NI_MAXSERV */
#ifndef NI_MAXHOST
# define NI_MAXHOST 1025
#endif /* !NI_MAXHOST */
#endif /* _FAKE_GETNAMEINFO_H */

596
lib/rbl.c
View file

@ -1,596 +0,0 @@
/*
rbl.c -- red-black tree + linked list convenience
Copyright (C) 2000 Ivo Timmermans <ivo@o2w.nl>,
2000 Guus Sliepen <guus@sliepen.eu.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: rbl.c,v 1.1.2.13 2002/06/21 10:11:11 guus Exp $
*/
#include "config.h"
#include <stdlib.h>
#include <xalloc.h>
#include "rbl.h"
#include <system.h>
/* Allocate a new rbl node */
rbl_t *new_rbl()
{
return (rbl_t *)xmalloc_and_zero(sizeof(rbl_t));
}
/* Free a rbl node */
void free_rbl(rbl_t *rbl)
{
if(rbl->data && rbl->tree->delete)
rbl->tree->delete(rbl->data);
free(rbl);
}
/* Allocate a new rbltree header */
rbltree_t *new_rbltree(rbl_compare_t compare, rbl_action_t delete)
{
rbltree_t *tree;
tree = (rbltree_t *)xmalloc_and_zero(sizeof(rbltree_t));
if(tree)
{
tree->compare = compare;
tree->delete = delete;
}
return tree;
}
/* Free a rbltree header */
void free_rbltree(rbltree_t *tree)
{
free(tree);
}
/* Search closest match in the tree */
rbl_t *rbl_search_closest_rbl(rbltree_t *tree, void *data)
{
rbl_t *rbl, *next;
int result;
next = rbl = tree->top;
while(next)
{
rbl = next;
result = tree->compare(data, rbl->data);
if(result < 0)
next = rbl->left;
else if(result > 0)
next = rbl->right;
else
break;
}
return rbl;
}
/* Search closest match in the tree */
rbl_t *rbl_search_closest_greater_rbl(rbltree_t *tree, void *data)
{
rbl_t *rbl;
rbl = rbl_search_closest_rbl(tree, data);
if(rbl)
{
if(tree->compare(data, rbl->data) > 0)
rbl = rbl->next;
}
return rbl;
}
/* Search closest match in the tree */
rbl_t *rbl_search_closest_smaller_rbl(rbltree_t *tree, void *data)
{
rbl_t *rbl;
rbl = rbl_search_closest_rbl(tree, data);
if(rbl)
{
if(tree->compare(data, rbl->data) < 0)
rbl = rbl->next;
}
return rbl;
}
void *rbl_search_closest(rbltree_t *tree, void *data)
{
rbl_t *rbl;
rbl = rbl_search_closest_rbl(tree, data);
if(rbl)
return rbl->data;
else
return NULL;
}
void *rbl_search_closest_greater(rbltree_t *tree, void *data)
{
rbl_t *rbl;
rbl = rbl_search_closest_greater_rbl(tree, data);
if(rbl)
return rbl->data;
else
return NULL;
}
void *rbl_search_closest_smaller(rbltree_t *tree, void *data)
{
rbl_t *rbl;
rbl = rbl_search_closest_smaller_rbl(tree, data);
if(rbl)
return rbl->data;
else
return NULL;
}
/* Search exact match or return NULL pointer */
rbl_t *rbl_search_rbl(rbltree_t *tree, void *data)
{
rbl_t *rbl;
int result;
rbl = tree->top;
while(rbl)
{
result = tree->compare(data, rbl->data);
if(result < 0)
rbl = rbl->left;
else if(result > 0)
rbl = rbl->right;
else
return rbl;
}
return NULL;
}
void *rbl_search(rbltree_t *tree, void *data)
{
rbl_t *rbl;
rbl = rbl_search_rbl(tree, data);
if(rbl)
return rbl->data;
else
return NULL;
}
/* Red-black tree operations taken from Introduction to Algorithms,
Cormen, Leiserson & Rivest, chapter 14.
*/
void rbl_left_rotate(rbl_t *x)
{
rbl_t *y;
y = x->right;
x->right = y->left;
if(y->left)
y->left->parent = x;
y->parent = x->parent;
if(!x->parent)
x->tree->top = y;
else
if(x == x->parent->left)
x->parent->left = y;
else
x->parent->right = y;
y->left = x;
x->parent = y;
}
void rbl_right_rotate(rbl_t *y)
{
rbl_t *x;
x = y->left;
y->left = x->right;
if(x->right)
x->right->parent = y;
x->parent = y->parent;
if(!y->parent)
y->tree->top = x;
else
if(y == y->parent->right)
y->parent->right = x;
else
y->parent->left = x;
x->right = y;
y->parent = x;
}
/* Insert a node into the rbl tree */
rbl_t *rbl_insert_rbl(rbltree_t *tree, rbl_t *rbl)
{
rbl_t *closest, *x, *y;
int result;
rbl->tree = tree;
/* Binary tree and linked list insert */
if(tree->top)
{
closest = rbl_search_closest_rbl(tree, rbl->data);
result = tree->compare(rbl->data, closest->data);
if(result < 0)
{
closest->left = rbl;
rbl->prev = closest->prev;
rbl->next = closest;
closest->prev = rbl;
if(rbl->prev)
rbl->prev->next = rbl;
else
tree->head = rbl;
}
else if(result > 0)
{
closest->right = rbl;
rbl->next = closest->next;
rbl->prev = closest;
closest->next = rbl;
if(rbl->next)
rbl->next->prev = rbl;
else
tree->tail = rbl;
}
else
return closest; /* Ofcourse, we cannot add two identical things */
rbl->parent = closest;
}
else
{
tree->top = rbl;
tree->head = rbl;
tree->tail = rbl;
}
/* Red-black part of insert */
x = rbl;
x->color = RBL_RED;
while(x != tree->top && x->parent->color == RBL_RED)
{
if(x->parent == x->parent->parent->left)
{
y = x->parent->parent->right;
if(y && y->color == RBL_RED)
{
x->parent->color = RBL_BLACK;
y->color = RBL_BLACK;
x->parent->parent->color = RBL_RED;
x = x->parent->parent;
}
else
{
if(x == x->parent->right)
{
x = x->parent;
rbl_left_rotate(x);
}
x->parent->color = RBL_BLACK;
x->parent->parent->color = RBL_RED;
rbl_right_rotate(x->parent->parent);
}
}
else
{
y = x->parent->parent->left;
if(y && y->color == RBL_RED)
{
x->parent->color = RBL_BLACK;
y->color = RBL_BLACK;
x->parent->parent->color = RBL_RED;
x = x->parent->parent;
}
else
{
if(x == x->parent->left)
{
x = x->parent;
rbl_right_rotate(x);
}
x->parent->color = RBL_BLACK;
x->parent->parent->color = RBL_RED;
rbl_left_rotate(x->parent->parent);
}
}
}
tree->top->color = RBL_BLACK;
return rbl;
}
/* Create a new node and insert it into the tree */
rbl_t *rbl_insert(rbltree_t *tree, void *data)
{
rbl_t *rbl;
rbl = new_rbl();
rbl->data = data;
if(rbl_insert_rbl(tree, rbl) == rbl)
return rbl;
else
{
free_rbl(rbl);
return NULL;
}
}
/* Restore red-black property after violation due to a deletion */
void rbl_delete_fixup(rbl_t *x)
{
rbl_t *w;
while(x != x->tree->top && x->color == RBL_BLACK)
{
if(x == x->parent->left)
{
w = x->parent->right;
if(w->color == RBL_RED)
{
w->color = RBL_BLACK;
x->parent->color = RBL_RED;
rbl_left_rotate(x->parent);
w = x->parent->right;
}
if(w->left->color == RBL_BLACK && w->right->color == RBL_BLACK)
{
w->color = RBL_RED;
x = x->parent;
}
else
{
if(w->right->color == RBL_BLACK)
{
w->left->color = RBL_BLACK;
w->color = RBL_RED;
rbl_right_rotate(w);
w = x->parent->right;
}
w->color = x->parent->color;
x->parent->color = RBL_BLACK;
w->right->color = RBL_BLACK;
rbl_left_rotate(x->parent);
x = x->tree->top;
}
}
else
{
w = x->parent->left;
if(w->color == RBL_RED)
{
w->color = RBL_BLACK;
x->parent->color = RBL_RED;
rbl_right_rotate(x->parent);
w = x->parent->left;
}
if(w->right->color == RBL_BLACK && w->left->color == RBL_BLACK)
{
w->color = RBL_RED;
x = x->parent;
}
else
{
if(w->left->color == RBL_BLACK)
{
w->right->color = RBL_BLACK;
w->color = RBL_RED;
rbl_left_rotate(w);
w = x->parent->left;
}
w->color = x->parent->color;
x->parent->color = RBL_BLACK;
w->left->color = RBL_BLACK;
rbl_right_rotate(x->parent);
x = x->tree->top;
}
}
}
x->color = RBL_BLACK;
}
/* Unlink node from the tree, but keep the node intact. */
rbl_t *rbl_unlink_rbl(rbl_t *rbl)
{
rbl_t *x, *y;
/* Binary tree delete */
if(rbl->left && rbl->right)
y = rbl->next;
else
y = rbl;
if(y->left)
x = y->left;
else
x = y->right;
if(x)
x->parent = y->parent;
if(!y->parent)
rbl->tree->top = x;
else
if(y == y->parent->left)
y->parent->left = x;
else
y->parent->right = x;
if(y != rbl)
{
y->left = rbl->left;
y->right = rbl->right;
y->parent = rbl->parent;
if(rbl == rbl->parent->left)
rbl->parent->left = y;
else
rbl->parent->right = y;
}
/* Linked list delete */
if(rbl->prev)
rbl->prev->next = rbl->next;
else
rbl->tree->head = rbl->next;
if(rbl->next)
rbl->next->prev = rbl->prev;
else
rbl->tree->tail = rbl->prev;
/* Red-black part of delete */
if(y->color == RBL_BLACK && x)
rbl_delete_fixup(x);
return rbl;
}
/* Search node in tree and unlink it */
rbl_t *rbl_unlink(rbltree_t *tree, void *data)
{
rbl_t *rbl;
rbl = rbl_search_rbl(tree, data);
if(rbl)
rbl_unlink_rbl(rbl);
return rbl;
}
/* Unlink node and free it */
void rbl_delete_rbl(rbl_t *rbl)
{
rbl_unlink_rbl(rbl);
free_rbl(rbl);
}
/* Search node in tree, unlink and free it */
void rbl_delete(rbltree_t *tree, void *data)
{
rbl_t *rbl;
rbl = rbl_unlink(tree, data);
if(rbl)
free_rbl(rbl);
}
/* Optimized unlinking for a complete tree */
void rbl_unlink_rbltree(rbltree_t *tree)
{
rbl_t *rbl, *next;
for(rbl = tree->head; rbl; rbl = next)
{
next = rbl->next;
rbl->tree = NULL;
rbl->parent = NULL;
rbl->left = NULL;
rbl->right = NULL;
rbl->prev = NULL;
rbl->next = NULL;
}
tree->top = NULL;
tree->head = NULL;
tree->tail = NULL;
}
/* Optimized deletion for a complete tree */
void rbl_delete_rbltree(rbltree_t *tree)
{
rbl_t *rbl, *next;
for(rbl = tree->head; rbl; rbl = next)
{
next = rbl->next;
free_rbl(rbl);
}
tree->top = NULL;
tree->head = NULL;
tree->tail = NULL;
}
/* Do action for each list entry (in order)
Deletion of entry for which action is called is allowed.
*/
void rbl_foreach(rbltree_t *tree, rbl_action_t action)
{
rbl_t *rbl, *next;
for(rbl = tree->head; rbl; rbl = next)
{
next = rbl->next;
action(rbl->data);
}
}
void rbl_foreach_rbl(rbltree_t *tree, rbl_action_rbl_t action)
{
rbl_t *rbl, *next;
for(rbl = tree->head; rbl; rbl = next)
{
next = rbl->next;
action(rbl);
}
}

104
lib/rbl.h
View file

@ -1,104 +0,0 @@
/*
rbl.h -- header file for rbl.c
Copyright (C) 2000 Ivo Timmermans <ivo@o2w.nl>,
2000 Guus Sliepen <guus@sliepen.eu.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: rbl.h,v 1.1.2.9 2002/06/21 10:11:11 guus Exp $
*/
#ifndef __RBL_H__
#define __RBL_H__
#define RBL_FOREACH(tree,rbl) for(rbl = tree->head; rbl; rbl = rbl->next)
typedef struct rbl_t
{
/* 'red-black tree' part */
struct rbltree_t *tree;
int color;
struct rbl_t *parent;
struct rbl_t *left;
struct rbl_t *right;
/* 'linked list' part */
struct rbl_t *prev;
struct rbl_t *next;
/* payload */
void *data;
} rbl_t;
typedef int (*rbl_compare_t) (const void *, const void *);
typedef void (*rbl_action_t) (const void *);
typedef void (*rbl_action_rbl_t) (const struct rbl_t *);
typedef struct rbltree_t
{
/* callback functions */
rbl_compare_t compare;
rbl_action_t delete;
/* tree part */
struct rbl_t *top;
/* linked list */
struct rbl_t *head;
struct rbl_t *tail;
} rbltree_t;
enum color
{
RBL_RED,
RBL_BLACK
} color;
extern rbltree_t *new_rbltree(rbl_compare_t, rbl_action_t);
extern void free_rbltree(rbltree_t *);
extern rbl_t *new_rbl(void);
extern void free_rbl(rbl_t *);
extern void *rbl_search(rbltree_t *, void *);
extern void *rbl_search_closest(rbltree_t *, void *);
extern void *rbl_search_closest_greater(rbltree_t *, void *);
extern void *rbl_search_closest_smaller(rbltree_t *, void *);
extern rbl_t *rbl_search_rbl(rbltree_t *, void *);
extern rbl_t *rbl_search_closest_rbl(rbltree_t *, void *);
extern rbl_t *rbl_search_closest_greater_rbl(rbltree_t *, void *);
extern rbl_t *rbl_search_closest_smaller_rbl(rbltree_t *, void *);
extern rbl_t *rbl_insert(rbltree_t *, void *);
extern rbl_t *rbl_unlink(rbltree_t *, void *);
extern void rbl_delete(rbltree_t *, void *);
extern rbl_t *rbl_insert_rbl(rbltree_t *, rbl_t *);
extern rbl_t *rbl_unlink_rbl(rbl_t *);
extern void rbl_delete_rbl(rbl_t *);
extern void rbl_unlink_rbltree(rbltree_t *);
extern void rbl_delete_rbltree(rbltree_t *);
extern void rbl_foreach(rbltree_t *, rbl_action_t);
extern void rbl_foreach_rbl(rbltree_t *, rbl_action_rbl_t);
#endif /* __RBL_H__ */

View file

@ -23,6 +23,9 @@
#include <ctype.h>
#include "fake-getaddrinfo.h"
#include "fake-getnameinfo.h"
enum {
DEBUG_NOTHING = 0, /* Quiet mode, only show starting/stopping of the daemon */
DEBUG_CONNECTIONS = 1, /* Show (dis)connects of other tinc daemons via TCP */