From 7910ce2a5c55211a4ea09a52832c6ed32c0b64fd Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Sat, 23 Feb 2002 19:02:25 +0000 Subject: [PATCH] updates. --- CHANGES | 19 ++++++++++++++++ TODO | 2 ++ configure.in.pre | 3 +++ lib/doc/programming_conv.html | 5 +++-- lib/silccore/silcpacket.h | 2 +- lib/silcutil/silcnet.c | 40 ++++++++++++++++++++++++++------- lib/silcutil/silcnet.h | 31 ++++++++++++++++--------- lib/silcutil/silcschedule.c | 14 ++++++++++++ lib/silcutil/silcschedule.h | 20 +++++++++++++++++ lib/silcutil/unix/silcunixnet.c | 22 ++++++++++++++++-- 10 files changed, 134 insertions(+), 24 deletions(-) diff --git a/CHANGES b/CHANGES index b56ca507..5ab19792 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,22 @@ +Sat Feb 23 20:31:43 EET 2002 Pekka Riikonen + + * Added `prefer_ipv6' argument to the functions + silc_net_gethostbyname[_async]. If it is TRUE it will return + IPv6 address over IPv4. If FALSE IPv4 address is returned + even if IPv6 address was found. Affected files + lib/silcutil/silcnet.[ch]. + + * Added support silc_net_create_connection[_async] to fallback + to IPv4 address if IPv6 address could not be used (like if + it doesn't work on a specific system). Affected file in + lib/silcutil/unix/silcunixnet.c. + +Sat Feb 23 15:20:30 EET 2002 Pekka Riikonen + + * Added silc_schedule_reinit function to do the enlarging + of the max tasks handling capabilities of the scheduler. + Affected files lib/silcutil/silcschedule.[ch]. + Wed Feb 20 20:41:01 EET 2002 Pekka Riikonen * Added automatic extern "C" { ... } for C++ compilers so the diff --git a/TODO b/TODO index 7e52a12a..0b9927e8 100644 --- a/TODO +++ b/TODO @@ -35,6 +35,8 @@ TODO/bugs In SILC Client Library TODO/bugs In SILC Server ======================== + o Remove old 0.6.x backwards support. + o Configuration file additions: o Add incoming connection frequency, incoming connection frequency diff --git a/configure.in.pre b/configure.in.pre index c8259d79..795dfded 100644 --- a/configure.in.pre +++ b/configure.in.pre @@ -805,6 +805,9 @@ lib/silcske/Makefile lib/silcutil/Makefile lib/silcutil/unix/Makefile lib/silcutil/win32/Makefile +lib/silcutil/beos/Makefile +lib/silcutil/os2/Makefile +lib/silcutil/epoc/Makefile lib/silcsftp/Makefile lib/silcsftp/tests/Makefile doc/example_silcd.conf diff --git a/lib/doc/programming_conv.html b/lib/doc/programming_conv.html index bd15c611..eee033b3 100644 --- a/lib/doc/programming_conv.html +++ b/lib/doc/programming_conv.html @@ -25,8 +25,9 @@ in the name. All macros start with the "SILC_" prefix. Example:
 
-Also defines (#define) are always capitalised and include underscores to -separate words in the name. Also all defines start with the "SILC_" prefix. +Also other defines (#define) are always capitalised and include +underscores to separate words in the name. Also all defines start with +the "SILC_" prefix.
 
Structures diff --git a/lib/silccore/silcpacket.h b/lib/silccore/silcpacket.h index 54d6bc16..87eee140 100644 --- a/lib/silccore/silcpacket.h +++ b/lib/silccore/silcpacket.h @@ -511,7 +511,7 @@ int silc_packet_receive(SilcSocketConnection sock); * * DESCRIPTION * - * Processes and decrypts the incmoing data, and calls parser callback + * Processes and decrypts the incoming data, and calls parser callback * for each received packet that will handle the actual packet parsing. * If more than one packet was received this calls the parser multiple * times. The parser callback will get context SilcPacketParserContext diff --git a/lib/silcutil/silcnet.c b/lib/silcutil/silcnet.c index d85317b9..630f9329 100644 --- a/lib/silcutil/silcnet.c +++ b/lib/silcutil/silcnet.c @@ -91,6 +91,7 @@ bool silc_net_is_ip(const char *addr) typedef struct { SilcNetResolveCallback completion; void *context; + bool prefer_ipv6; SilcSchedule schedule; char *input; char *result; @@ -116,7 +117,7 @@ static void *silc_net_gethostbyname_thread(void *context) SilcNetResolveContext r = (SilcNetResolveContext)context; char tmp[64]; - if (silc_net_gethostbyname(r->input, tmp, sizeof(tmp))) + if (silc_net_gethostbyname(r->input, r->prefer_ipv6, tmp, sizeof(tmp))) r->result = strdup(tmp); silc_schedule_task_add(r->schedule, 0, silc_net_resolve_completion, r, 0, 1, @@ -143,24 +144,45 @@ static void *silc_net_gethostbyaddr_thread(void *context) /* Resolves IP address for hostname. */ -bool silc_net_gethostbyname(const char *name, char *address, +bool silc_net_gethostbyname(const char *name, bool prefer_ipv6, char *address, uint32 address_len) { #ifdef HAVE_IPV6 - struct addrinfo hints, *ai; + struct addrinfo hints, *ai, *tmp, *ip4 = NULL, *ip6 = NULL; memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; if (getaddrinfo(name, NULL, &hints, &ai)) return FALSE; - if (getnameinfo(ai->ai_addr, ai->ai_addrlen, address, - address_len, NULL, 0, NI_NUMERICHOST)) { + for (tmp = ai; tmp; tmp = tmp->ai_next) { + if (tmp->ai_family == AF_INET6) { + ip6 = tmp; + if (ip4) + break; + continue; + } + if (tmp->ai_family == AF_INET) { + ip4 = tmp; + if (ip6) + break; + continue; + } + } + + tmp = (prefer_ipv6 ? (ip6 ? ip6 : ip4) : (ip4 ? ip4 : ip6)); + if (!tmp) { freeaddrinfo(ai); return FALSE; - } else { + } + + if (getnameinfo(tmp->ai_addr, tmp->ai_addrlen, address, + address_len, NULL, 0, NI_NUMERICHOST)) { freeaddrinfo(ai); + return FALSE; } + + freeaddrinfo(ai); #else struct hostent *hp; struct in_addr ip; @@ -186,6 +208,7 @@ bool silc_net_gethostbyname(const char *name, char *address, /* Resolves IP address for hostname async. */ void silc_net_gethostbyname_async(const char *name, + bool prefer_ipv6, SilcSchedule schedule, SilcNetResolveCallback completion, void *context) @@ -194,6 +217,7 @@ void silc_net_gethostbyname_async(const char *name, r->completion = completion; r->context = context; + r->prefer_ipv6 = prefer_ipv6; r->schedule = schedule; r->input = strdup(name); @@ -453,7 +477,7 @@ char *silc_net_localhost(void) if (gethostname(hostname, sizeof(hostname))) return NULL; - if (!silc_net_gethostbyname(hostname, ip_addr, sizeof(ip_addr))) + if (!silc_net_gethostbyname(hostname, TRUE, ip_addr, sizeof(ip_addr))) return strdup(hostname); silc_net_gethostbyaddr(ip_addr, hostname, sizeof(hostname)); @@ -469,7 +493,7 @@ char *silc_net_localip(void) if (gethostname(hostname, sizeof(hostname))) return NULL; - if (!silc_net_gethostbyname(hostname, ip_addr, sizeof(ip_addr))) + if (!silc_net_gethostbyname(hostname, TRUE, ip_addr, sizeof(ip_addr))) return NULL; return strdup(ip_addr); diff --git a/lib/silcutil/silcnet.h b/lib/silcutil/silcnet.h index 0e85a1bd..3001ff26 100644 --- a/lib/silcutil/silcnet.h +++ b/lib/silcutil/silcnet.h @@ -252,18 +252,21 @@ typedef void (*SilcNetResolveCallback)(const char *result, void *context); * * SYNOPSIS * - * bool silc_net_gethostbyname(const char *name, char *address, - * uint32 address_len); + * bool silc_net_gethostbyname(const char *name, bool prefer_ipv6, + * char *address, uint32 address_len); * * DESCRIPTION * - * Resolves the IP address of the hostname indicated by the `host'. - * This returns TRUE and the IP address of the host, or FALSE - * if the address could not be resolved. This is synchronous - * function and will block the calling process. + * Resolves the IP address of the hostname indicated by the `name'. + * This returns TRUE and the IP address of the host to the `address' + * buffer, or FALSE if the address could not be resolved. This is + * synchronous function and will block the calling process. If the + * `prefer_ipv6' is TRUE then this will return IPv6 address if it + * finds. If FALSE if returns IPv4 address even if it found IPv6 + * address also. * ***/ -bool silc_net_gethostbyname(const char *name, char *address, +bool silc_net_gethostbyname(const char *name, bool prefer_ipv6, char *address, uint32 address_len); /****f* silcutil/SilcNetAPI/silc_net_gethostbyname_async @@ -271,6 +274,7 @@ bool silc_net_gethostbyname(const char *name, char *address, * SYNOPSIS * * void silc_net_gethostbyname_async(const char *name, + * bool prefer_ipv6, * SilcSchedule schedule, * SilcNetResolveCallback completion, * void *context) @@ -278,12 +282,17 @@ bool silc_net_gethostbyname(const char *name, char *address, * DESCRIPTION * * Asynchronously resolves the IP address of the hostname indicated - * by the `host'. This function returns immediately, and the + * by the `name'. This function returns immediately, and the * `completion' callback will be called after the resolving is * completed. * + * If the `prefer_ipv6' is TRUE then this will return IPv6 address if it + * finds. If FALSE if returns IPv4 address even if it found IPv6 + * address also. + * ***/ void silc_net_gethostbyname_async(const char *name, + bool prefer_ipv6, SilcSchedule schedule, SilcNetResolveCallback completion, void *context); @@ -298,9 +307,9 @@ void silc_net_gethostbyname_async(const char *name, * DESCRIPTION * * Resolves the hostname for the IP address indicated by the `addr' - * This returns TRUE and the resolved hostname, or FALSE on error. - * The `addr' may be either IPv4 or IPv6 address. This is - * synchronous function and will block the calling process. + * This returns TRUE and the resolved hostname to the `name' buffer, + * or FALSE on error. The `addr' may be either IPv4 or IPv6 address. + * This is synchronous function and will block the calling process. * ***/ bool silc_net_gethostbyaddr(const char *addr, char *name, uint32 name_len); diff --git a/lib/silcutil/silcschedule.c b/lib/silcutil/silcschedule.c index 1672fdff..4084371e 100644 --- a/lib/silcutil/silcschedule.c +++ b/lib/silcutil/silcschedule.c @@ -250,6 +250,20 @@ bool silc_schedule_uninit(SilcSchedule schedule) return TRUE; } +/* Enlarge the capabilities of the scheduler to handle tasks to `max_tasks'. */ + +bool silc_schedule_reinit(SilcSchedule schedule, int max_tasks) +{ + silc_mutex_lock(schedule->lock); + if (schedule->max_fd <= max_tasks) + return FALSE; + schedule->fd_list = silc_realloc(schedule->fd_list, + (sizeof(*schedule->fd_list) * max_tasks)); + schedule->max_fd = max_tasks; + silc_mutex_unlock(schedule->lock); + return TRUE; +} + /* Stops the schedule even if it is not supposed to be stopped yet. After calling this, one should call silc_schedule_uninit (after the silc_schedule has returned). */ diff --git a/lib/silcutil/silcschedule.h b/lib/silcutil/silcschedule.h index 45a5defa..eb0e0fbc 100644 --- a/lib/silcutil/silcschedule.h +++ b/lib/silcutil/silcschedule.h @@ -316,6 +316,26 @@ SilcSchedule silc_schedule_init(int max_tasks); ***/ bool silc_schedule_uninit(SilcSchedule schedule); +/****f* silcutil/SilcScheduleAPI/silc_schedule_reinit + * + * SYNOPSIS + * + * SilcSchedule silc_schedule_reinit(int max_tasks); + * + * DESCRIPTION + * + * This function can be called to enlarge the task handling capabilities + * of the scheduler indicated by `schedule'. The `max_tasks' must be + * larger than what was set in silc_schedule_init function. This function + * returns FALSE if it cannot reinit the scheduler. This function does + * not do anything else except ready the scheduler to handle `max_tasks' + * number of tasks after this function returns. It is safe to call this + * function at any time, and it is guaranteed that existing tasks remain + * as they are in the scheduler. + * + ***/ +bool silc_schedule_reinit(SilcSchedule schedule, int max_tasks); + /****f* silcutil/SilcScheduleAPI/silc_schedule_stop * * SYNOPSIS diff --git a/lib/silcutil/unix/silcunixnet.c b/lib/silcutil/unix/silcunixnet.c index d1f6384c..48b17e16 100644 --- a/lib/silcutil/unix/silcunixnet.c +++ b/lib/silcutil/unix/silcunixnet.c @@ -155,11 +155,13 @@ int silc_net_create_connection(const char *local_ip, int port, int sock, rval; char ip_addr[64]; SilcSockaddr desthost; + bool prefer_ipv6 = TRUE; SILC_LOG_DEBUG(("Creating connection to host %s port %d", host, port)); /* Do host lookup */ - if (!silc_net_gethostbyname(host, ip_addr, sizeof(ip_addr))) { + retry: + if (!silc_net_gethostbyname(host, prefer_ipv6, ip_addr, sizeof(ip_addr))) { SILC_LOG_ERROR(("Network (%s) unreachable: could not resolve the " "IP address", host)); return -1; @@ -172,6 +174,13 @@ int silc_net_create_connection(const char *local_ip, int port, /* Create the connection socket */ sock = socket(desthost.sin.sin_family, SOCK_STREAM, 0); if (sock < 0) { + /* If address is IPv6, then fallback to IPv4 and see whether we can do + better with that on socket creation. */ + if (prefer_ipv6 && silc_net_is_ip6(ip_addr)) { + prefer_ipv6 = FALSE; + goto retry; + } + SILC_LOG_ERROR(("Cannot create socket: %s", strerror(errno))); return -1; } @@ -216,12 +225,14 @@ int silc_net_create_connection_async(const char *local_ip, int port, int sock, rval; char ip_addr[64]; SilcSockaddr desthost; + bool prefer_ipv6 = TRUE; SILC_LOG_DEBUG(("Creating connection (async) to host %s port %d", host, port)); /* Do host lookup */ - if (!silc_net_gethostbyname(host, ip_addr, sizeof(ip_addr))) { + retry: + if (!silc_net_gethostbyname(host, prefer_ipv6, ip_addr, sizeof(ip_addr))) { SILC_LOG_ERROR(("Network (%s) unreachable: could not resolve the " "IP address", host)); return -1; @@ -234,6 +245,13 @@ int silc_net_create_connection_async(const char *local_ip, int port, /* Create the connection socket */ sock = socket(desthost.sin.sin_family, SOCK_STREAM, 0); if (sock < 0) { + /* If address is IPv6, then fallback to IPv4 and see whether we can do + better with that on socket creation. */ + if (prefer_ipv6 && silc_net_is_ip6(ip_addr)) { + prefer_ipv6 = FALSE; + goto retry; + } + SILC_LOG_ERROR(("Cannot create socket: %s", strerror(errno))); return -1; } -- 2.24.0