Merge branch 'async_dns_api'
This commit is contained in:
commit
2d2ccc0039
@ -19,9 +19,6 @@
|
|||||||
|
|
||||||
#include "uhub.h"
|
#include "uhub.h"
|
||||||
|
|
||||||
// #define DEBUG_LOOKUP_TIME 1
|
|
||||||
#define MAX_CONCURRENT_JOBS 25
|
|
||||||
|
|
||||||
static struct net_dns_job* find_and_remove_job(struct net_dns_job* job);
|
static struct net_dns_job* find_and_remove_job(struct net_dns_job* job);
|
||||||
static struct net_dns_result* find_and_remove_result(struct net_dns_job* job);
|
static struct net_dns_result* find_and_remove_result(struct net_dns_job* job);
|
||||||
|
|
||||||
@ -56,6 +53,22 @@ static void free_job(struct net_dns_job* job)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void shutdown_free_jobs(void* ptr)
|
||||||
|
{
|
||||||
|
struct net_dns_job* job = (struct net_dns_job*) ptr;
|
||||||
|
uhub_thread_cancel(job->thread_handle);
|
||||||
|
uhub_thread_join(job->thread_handle);
|
||||||
|
free_job(job);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void shutdown_free_results(void* ptr)
|
||||||
|
{
|
||||||
|
struct net_dns_result* result = (struct net_dns_result*) ptr;
|
||||||
|
uhub_thread_join(result->job->thread_handle);
|
||||||
|
net_dns_result_free(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// NOTE: Any job manipulating the members of this
|
// NOTE: Any job manipulating the members of this
|
||||||
// struct must lock the mutex!
|
// struct must lock the mutex!
|
||||||
struct net_dns_subsystem
|
struct net_dns_subsystem
|
||||||
@ -79,19 +92,21 @@ void net_dns_initialize()
|
|||||||
void net_dns_destroy()
|
void net_dns_destroy()
|
||||||
{
|
{
|
||||||
struct net_dns_job* job;
|
struct net_dns_job* job;
|
||||||
|
struct net_dns_result* result;
|
||||||
|
|
||||||
uhub_mutex_lock(&g_dns->mutex);
|
uhub_mutex_lock(&g_dns->mutex);
|
||||||
LOG_TRACE("net_dns_destroy(): jobs=%d", (int) list_size(g_dns->jobs));
|
LOG_TRACE("net_dns_destroy(): jobs=%d", (int) list_size(g_dns->jobs));
|
||||||
job = (struct net_dns_job*) list_get_first(g_dns->jobs);
|
list_clear(g_dns->jobs, &shutdown_free_jobs);
|
||||||
|
|
||||||
|
LOG_TRACE("net_dns_destroy(): results=%d", (int) list_size(g_dns->results));
|
||||||
|
list_clear(g_dns->results, &shutdown_free_results);
|
||||||
uhub_mutex_unlock(&g_dns->mutex);
|
uhub_mutex_unlock(&g_dns->mutex);
|
||||||
|
|
||||||
while (job)
|
list_destroy(g_dns->jobs);
|
||||||
{
|
list_destroy(g_dns->results);
|
||||||
net_dns_job_cancel(job);
|
uhub_mutex_destroy(&g_dns->mutex);
|
||||||
|
hub_free(g_dns);
|
||||||
uhub_mutex_lock(&g_dns->mutex);
|
g_dns = NULL;
|
||||||
job = (struct net_dns_job*) list_get_first(g_dns->jobs);
|
|
||||||
uhub_mutex_unlock(&g_dns->mutex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dummy_free(void* ptr)
|
static void dummy_free(void* ptr)
|
||||||
@ -149,9 +164,9 @@ static void* job_thread_resolve_name(void* ptr)
|
|||||||
hints.ai_protocol = IPPROTO_TCP;
|
hints.ai_protocol = IPPROTO_TCP;
|
||||||
|
|
||||||
ret = getaddrinfo(job->host, NULL, &hints, &result);
|
ret = getaddrinfo(job->host, NULL, &hints, &result);
|
||||||
if (ret != 0)
|
if (ret != 0 && ret != EAI_NONAME)
|
||||||
{
|
{
|
||||||
LOG_WARN("getaddrinfo() failed: %s", gai_strerror(ret));
|
LOG_TRACE("getaddrinfo() failed: %s", gai_strerror(ret));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,32 +174,39 @@ static void* job_thread_resolve_name(void* ptr)
|
|||||||
dns_results->addr_list = list_create();
|
dns_results->addr_list = list_create();
|
||||||
dns_results->job = job;
|
dns_results->job = job;
|
||||||
|
|
||||||
for (it = result; it; it = it->ai_next)
|
if (ret != EAI_NONAME)
|
||||||
{
|
{
|
||||||
struct ip_addr_encap* ipaddr = hub_malloc_zero(sizeof(struct ip_addr_encap));
|
for (it = result; it; it = it->ai_next)
|
||||||
ipaddr->af = it->ai_family;
|
{
|
||||||
|
struct ip_addr_encap* ipaddr = hub_malloc_zero(sizeof(struct ip_addr_encap));
|
||||||
|
ipaddr->af = it->ai_family;
|
||||||
|
|
||||||
if (it->ai_family == AF_INET)
|
if (it->ai_family == AF_INET)
|
||||||
{
|
{
|
||||||
struct sockaddr_in* addr4 = (struct sockaddr_in*) it->ai_addr;
|
struct sockaddr_in* addr4 = (struct sockaddr_in*) it->ai_addr;
|
||||||
memcpy(&ipaddr->internal_ip_data.in, &addr4->sin_addr, sizeof(struct in_addr));
|
memcpy(&ipaddr->internal_ip_data.in, &addr4->sin_addr, sizeof(struct in_addr));
|
||||||
}
|
}
|
||||||
else if (it->ai_family == AF_INET6)
|
else if (it->ai_family == AF_INET6)
|
||||||
{
|
{
|
||||||
struct sockaddr_in6* addr6 = (struct sockaddr_in6*) it->ai_addr;
|
struct sockaddr_in6* addr6 = (struct sockaddr_in6*) it->ai_addr;
|
||||||
memcpy(&ipaddr->internal_ip_data.in6, &addr6->sin6_addr, sizeof(struct in6_addr));
|
memcpy(&ipaddr->internal_ip_data.in6, &addr6->sin6_addr, sizeof(struct in6_addr));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG_WARN("getaddrinfo() returned result with unknown address family: %d", it->ai_family);
|
LOG_TRACE("getaddrinfo() returned result with unknown address family: %d", it->ai_family);
|
||||||
hub_free(ipaddr);
|
hub_free(ipaddr);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_WARN("getaddrinfo() - Address (%d): %s", ret++, ip_convert_to_string(ipaddr));
|
LOG_DUMP("getaddrinfo() - Address (%d) %s for \"%s\"", ret++, ip_convert_to_string(ipaddr), job->host);
|
||||||
list_append(dns_results->addr_list, ipaddr);
|
list_append(dns_results->addr_list, ipaddr);
|
||||||
|
}
|
||||||
|
freeaddrinfo(result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* hm */
|
||||||
}
|
}
|
||||||
freeaddrinfo(result);
|
|
||||||
|
|
||||||
#ifdef DEBUG_LOOKUP_TIME
|
#ifdef DEBUG_LOOKUP_TIME
|
||||||
gettimeofday(&job->time_finish, NULL);
|
gettimeofday(&job->time_finish, NULL);
|
||||||
|
@ -508,6 +508,7 @@ void ADC_client_send_info(struct ADC_client* client)
|
|||||||
ADC_TRACE;
|
ADC_TRACE;
|
||||||
client->info = adc_msg_construct_source(ADC_CMD_BINF, client->sid, 96);
|
client->info = adc_msg_construct_source(ADC_CMD_BINF, client->sid, 96);
|
||||||
|
|
||||||
|
|
||||||
adc_msg_add_named_argument_string(client->info, ADC_INF_FLAG_NICK, client->nick);
|
adc_msg_add_named_argument_string(client->info, ADC_INF_FLAG_NICK, client->nick);
|
||||||
|
|
||||||
if (client->desc)
|
if (client->desc)
|
||||||
@ -528,6 +529,7 @@ void ADC_client_send_info(struct ADC_client* client)
|
|||||||
adc_msg_add_named_argument_int(client->info, ADC_INF_FLAG_UPLOAD_SPEED, 10 * 1024 * 1024);
|
adc_msg_add_named_argument_int(client->info, ADC_INF_FLAG_UPLOAD_SPEED, 10 * 1024 * 1024);
|
||||||
|
|
||||||
adc_cid_pid(client);
|
adc_cid_pid(client);
|
||||||
|
|
||||||
ADC_client_send(client, client->info);
|
ADC_client_send(client, client->info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,6 +567,7 @@ void ADC_client_destroy(struct ADC_client* client)
|
|||||||
hub_free(client->nick);
|
hub_free(client->nick);
|
||||||
hub_free(client->desc);
|
hub_free(client->desc);
|
||||||
hub_free(client->address.hostname);
|
hub_free(client->address.hostname);
|
||||||
|
hub_free(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ADC_client_connect(struct ADC_client* client, const char* address)
|
int ADC_client_connect(struct ADC_client* client, const char* address)
|
||||||
@ -577,19 +580,20 @@ int ADC_client_connect(struct ADC_client* client, const char* address)
|
|||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if (client->state == ps_dns)
|
return ADC_client_connect_internal(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ADC_client_connect_internal(struct ADC_client* client)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
if (client->state == ps_dns)
|
||||||
{
|
{
|
||||||
// Done name resolving!
|
// Done name resolving!
|
||||||
client->callback(client, ADC_CLIENT_CONNECTING, 0);
|
client->callback(client, ADC_CLIENT_CONNECTING, 0);
|
||||||
ADC_client_set_state(client, ps_conn);
|
ADC_client_set_state(client, ps_conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ADC_client_connect_internal(client);
|
ret = net_connect(net_con_get_sd(client->con), (struct sockaddr*) &client->addr, sizeof(struct sockaddr_in));
|
||||||
}
|
|
||||||
|
|
||||||
int ADC_client_connect_internal(struct ADC_client* client)
|
|
||||||
{
|
|
||||||
int ret = net_connect(net_con_get_sd(client->con), (struct sockaddr*) &client->addr, sizeof(struct sockaddr_in));
|
|
||||||
if (ret == 0 || (ret == -1 && net_error() == EISCONN))
|
if (ret == 0 || (ret == -1 && net_error() == EISCONN))
|
||||||
{
|
{
|
||||||
ADC_client_on_connected(client);
|
ADC_client_on_connected(client);
|
||||||
@ -622,10 +626,12 @@ static void ADC_client_on_connected(struct ADC_client* client)
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
struct adc_message* handshake = adc_msg_create(ADC_HANDSHAKE);
|
||||||
net_con_update(client->con, NET_EVENT_READ);
|
net_con_update(client->con, NET_EVENT_READ);
|
||||||
client->callback(client, ADC_CLIENT_CONNECTED, 0);
|
client->callback(client, ADC_CLIENT_CONNECTED, 0);
|
||||||
ADC_client_send(client, adc_msg_create(ADC_HANDSHAKE));
|
ADC_client_send(client, handshake);
|
||||||
ADC_client_set_state(client, ps_protocol);
|
ADC_client_set_state(client, ps_protocol);
|
||||||
|
adc_msg_free(handshake);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -633,11 +639,13 @@ static void ADC_client_on_connected(struct ADC_client* client)
|
|||||||
static void ADC_client_on_connected_ssl(struct ADC_client* client)
|
static void ADC_client_on_connected_ssl(struct ADC_client* client)
|
||||||
{
|
{
|
||||||
ADC_TRACE;
|
ADC_TRACE;
|
||||||
|
struct adc_message* handshake = adc_msg_create(ADC_HANDSHAKE);
|
||||||
client->callback(client, ADC_CLIENT_SSL_OK, 0);
|
client->callback(client, ADC_CLIENT_SSL_OK, 0);
|
||||||
client->callback(client, ADC_CLIENT_CONNECTED, 0);
|
client->callback(client, ADC_CLIENT_CONNECTED, 0);
|
||||||
net_con_update(client->con, NET_EVENT_READ);
|
net_con_update(client->con, NET_EVENT_READ);
|
||||||
ADC_client_send(client, adc_msg_create(ADC_HANDSHAKE));
|
ADC_client_send(client, handshake);
|
||||||
ADC_client_set_state(client, ps_protocol);
|
ADC_client_set_state(client, ps_protocol);
|
||||||
|
adc_msg_free(handshake);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -35,7 +35,6 @@ static struct ADC_user* user_get(sid_t sid)
|
|||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void user_remove(const struct ADC_client_quit_reason* quit)
|
static void user_remove(const struct ADC_client_quit_reason* quit)
|
||||||
{
|
{
|
||||||
struct ADC_user* user = user_get(quit->sid);
|
struct ADC_user* user = user_get(quit->sid);
|
||||||
@ -162,6 +161,68 @@ static int handle(struct ADC_client* client, enum ADC_client_callback_type type,
|
|||||||
|
|
||||||
static int running = 1;
|
static int running = 1;
|
||||||
|
|
||||||
|
#if !defined(WIN32)
|
||||||
|
void adm_handle_signal(int sig)
|
||||||
|
{
|
||||||
|
switch (sig)
|
||||||
|
{
|
||||||
|
case SIGINT:
|
||||||
|
LOG_INFO("Interrupted. Shutting down...");
|
||||||
|
running = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIGTERM:
|
||||||
|
LOG_INFO("Terminated. Shutting down...");
|
||||||
|
running = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIGPIPE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIGHUP:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOG_TRACE("hub_handle_signal(): caught unknown signal: %d", signal);
|
||||||
|
running = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int signals[] =
|
||||||
|
{
|
||||||
|
SIGINT, /* Interrupt the application */
|
||||||
|
SIGTERM, /* Terminate the application */
|
||||||
|
SIGPIPE, /* prevent sigpipe from kills the application */
|
||||||
|
SIGHUP, /* reload configuration */
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
void adm_setup_signal_handlers()
|
||||||
|
{
|
||||||
|
sigset_t sig_set;
|
||||||
|
struct sigaction act;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
sigemptyset(&sig_set);
|
||||||
|
act.sa_mask = sig_set;
|
||||||
|
act.sa_flags = SA_ONSTACK | SA_RESTART;
|
||||||
|
act.sa_handler = adm_handle_signal;
|
||||||
|
|
||||||
|
for (i = 0; signals[i]; i++)
|
||||||
|
{
|
||||||
|
if (sigaction(signals[i], &act, 0) != 0)
|
||||||
|
{
|
||||||
|
LOG_ERROR("Error setting signal handler %d", signals[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void adm_shutdown_signal_handlers()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif /* !WIN32 */
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
@ -170,6 +231,9 @@ int main(int argc, char** argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hub_set_log_verbosity(5);
|
||||||
|
adm_setup_signal_handlers();
|
||||||
|
|
||||||
struct ADC_client* client;
|
struct ADC_client* client;
|
||||||
net_initialize();
|
net_initialize();
|
||||||
|
|
||||||
@ -183,6 +247,7 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
ADC_client_destroy(client);
|
ADC_client_destroy(client);
|
||||||
net_destroy();
|
net_destroy();
|
||||||
|
adm_shutdown_signal_handlers();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,12 @@
|
|||||||
#include "uhub.h"
|
#include "uhub.h"
|
||||||
|
|
||||||
#ifdef POSIX_THREAD_SUPPORT
|
#ifdef POSIX_THREAD_SUPPORT
|
||||||
|
|
||||||
|
struct pthread_data
|
||||||
|
{
|
||||||
|
pthread_t handle;
|
||||||
|
};
|
||||||
|
|
||||||
void uhub_mutex_init(uhub_mutex_t* mutex)
|
void uhub_mutex_init(uhub_mutex_t* mutex)
|
||||||
{
|
{
|
||||||
pthread_mutex_init(mutex, NULL);
|
pthread_mutex_init(mutex, NULL);
|
||||||
@ -48,23 +54,25 @@ int uhub_mutex_trylock(uhub_mutex_t* mutex)
|
|||||||
|
|
||||||
uhub_thread_t* uhub_thread_create(uhub_thread_start start, void* arg)
|
uhub_thread_t* uhub_thread_create(uhub_thread_start start, void* arg)
|
||||||
{
|
{
|
||||||
uhub_thread_t* thread = (uhub_thread_t*) hub_malloc_zero(sizeof(uhub_thread_t));
|
struct pthread_data* thread = (struct pthread_data*) hub_malloc_zero(sizeof(struct pthread_data));
|
||||||
int ret = pthread_create(thread, NULL, start, arg);
|
int ret = pthread_create(&thread->handle, NULL, start, arg);
|
||||||
if (ret == 0)
|
if (ret != 0)
|
||||||
return thread;
|
{
|
||||||
hub_free(thread);
|
hub_free(thread);
|
||||||
return NULL;
|
thread = NULL;
|
||||||
|
}
|
||||||
|
return thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uhub_thread_cancel(uhub_thread_t* thread)
|
void uhub_thread_cancel(uhub_thread_t* thread)
|
||||||
{
|
{
|
||||||
pthread_cancel(thread);
|
pthread_cancel(thread->handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* uhub_thread_join(uhub_thread_t* thread)
|
void* uhub_thread_join(uhub_thread_t* thread)
|
||||||
{
|
{
|
||||||
void* ret = NULL;
|
void* ret = NULL;
|
||||||
pthread_join(thread, &ret);
|
pthread_join(thread->handle, &ret);
|
||||||
hub_free(thread);
|
hub_free(thread);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
typedef void*(*uhub_thread_start)(void*) ;
|
typedef void*(*uhub_thread_start)(void*) ;
|
||||||
|
|
||||||
#ifdef POSIX_THREAD_SUPPORT
|
#ifdef POSIX_THREAD_SUPPORT
|
||||||
typedef pthread_t uhub_thread_t;
|
typedef struct pthread_data uhub_thread_t;
|
||||||
typedef pthread_mutex_t uhub_mutex_t;
|
typedef pthread_mutex_t uhub_mutex_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user