Commit 5f7197f4 authored by Simon Morlat's avatar Simon Morlat

DNS api in progress

parent c5ae5400
......@@ -18,9 +18,10 @@
#ifndef BELLE_SIP_H
#define BELLE_SIP_H
#include "belle-sip/uri.h"
#include "belle-sip/list.h"
#include "belle-sip/mainloop.h"
#include "belle-sip/uri.h"
#undef TRUE
#define TRUE 1
......
......@@ -19,24 +19,72 @@
#ifndef BELLE_SIP_MAINLOOP_H
#define BELLE_SIP_MAINLOOP_H
#define BELLE_SIP_EVENT_READ 1
#define BELLE_SIP_EVENT_WRITE (1<<1)
#define BELLE_SIP_EVENT_ERROR (1<<2)
#define BELLE_SIP_EVENT_TIMEOUT (1<<3)
typedef struct belle_sip_source belle_sip_source_t;
typedef int (*belle_sip_source_func_t)(void *user_data, unsigned int events);
belle_sip_source_t * belle_sip_timeout_source_new(belle_sip_source_func_t func, void *data, unsigned int timeout_value_ms);
/**
* Callback function prototype for main loop notifications.
* Return value is important:
* 0 => source is removed from main loop.
* non zero value => source is kept.
**/
typedef int (*belle_sip_source_func_t)(void *user_data, unsigned int events);
typedef struct belle_sip_main_loop belle_sip_main_loop_t;
belle_sip_main_loop_t *belle_sip_main_loop_new(void);
void belle_sip_main_loop_add_source(belle_sip_main_loop_t *ml, belle_sip_source_t *source);
void belle_sip_main_loop_remove_source(belle_sip_main_loop_t *ml, belle_sip_source_t *source);
void belle_sip_main_loop_add_timeout(belle_sip_main_loop_t *ml, belle_sip_source_func_t func, void *data, unsigned int timeout_value_ms);
/**
* Creates a mainloop.
**/
belle_sip_main_loop_t *belle_sip_main_loop_new(void);
/**
* Adds a timeout into the main loop
* @param ml
* @param func a callback function to be called to notify timeout expiration
* @param data a pointer to be passed to the callback
* @param timeout_value_ms duration of the timeout.
* @returns timeout id
**/
unsigned long belle_sip_main_loop_add_timeout(belle_sip_main_loop_t *ml, belle_sip_source_func_t func, void *data, unsigned int timeout_value_ms);
/**
* Creates a timeout source, similarly to belle_sip_main_loop_add_timeout().
* However in this case the timeout must be entered manually using belle_sip_main_loop_add_source().
* Its pointer can be used to remove it from the source (that is cancelling it).
**/
belle_sip_source_t * belle_sip_timeout_source_new(belle_sip_source_func_t func, void *data, unsigned int timeout_value_ms);
/**
* Executes the main loop forever (or until belle_sip_main_loop_quit() is called)
**/
void belle_sip_main_loop_run(belle_sip_main_loop_t *ml);
/**
* Executes the main loop for the time specified in milliseconds.
**/
void belle_sip_main_loop_sleep(belle_sip_main_loop_t *ml, int milliseconds);
/**
* Break out the main loop.
**/
void belle_sip_main_loop_quit(belle_sip_main_loop_t *ml);
/**
* Cancel (removes) a source. It is not freed.
**/
void belle_sip_main_loop_cancel_source(belle_sip_main_loop_t *ml, unsigned long id);
#endif
......@@ -23,7 +23,8 @@ lib_LTLIBRARIES=libbellesip.la
libbellesip_la_SOURCES=belle_sip_uri_impl.c \
belle_sip_utils.c belle_sip_internal.h \
belle_sip_loop.c
belle_sip_loop.c \
belle_sip_resolver.c belle_sip_resolver.h
libbellesip_la_CFLAGS=$(STRICT_OPTIONS)
......
......@@ -8,8 +8,9 @@
#include <stdio.h>
#include <stdint.h>
#include <errno.h>
#include <unistd.h>
#include "belle-sip/list.h"
#include "belle-sip/belle-sip.h"
struct _belle_sip_list {
struct _belle_sip_list *next;
......@@ -17,8 +18,22 @@ struct _belle_sip_list {
void *data;
};
typedef void (*belle_sip_source_remove_callback_t)(belle_sip_source_t *);
struct belle_sip_source{
belle_sip_list_t node;
unsigned long id;
int fd;
unsigned int events;
int timeout;
void *data;
uint64_t expire_ms;
int index; /* index in pollfd table */
belle_sip_source_func_t notify;
belle_sip_source_remove_callback_t on_remove;
};
void belle_sip_fd_source_init(belle_sip_source_t *s, belle_sip_source_func_t func, void *data, int fd, unsigned int events, unsigned int timeout_value_ms);
#define belle_list_next(elem) ((elem)->next)
......@@ -31,6 +46,7 @@ void *belle_sip_malloc(size_t size);
void *belle_sip_malloc0(size_t size);
void *belle_sip_realloc(void *ptr, size_t size);
void belle_sip_free(void *ptr);
char * belle_sip_strdup(const char *s);
#define belle_sip_new(type) (type*)belle_sip_malloc(sizeof(type))
#define belle_sip_new0(type) (type*)belle_sip_malloc0(sizeof(type))
......
......@@ -22,17 +22,6 @@
#include <unistd.h>
#include <poll.h>
struct belle_sip_source{
belle_sip_list_t node;
int fd;
unsigned int events;
int timeout;
void *data;
uint64_t expire_ms;
int index; /* index in pollfd table */
belle_sip_source_func_t notify;
void (*on_remove)(belle_sip_source_t *);
};
void belle_sip_source_destroy(belle_sip_source_t *obj){
if (obj->node.next || obj->node.prev){
......@@ -41,13 +30,19 @@ void belle_sip_source_destroy(belle_sip_source_t *obj){
belle_sip_free(obj);
}
static belle_sip_source_t * belle_sip_fd_source_new(belle_sip_source_func_t func, void *data, int fd, unsigned int events, unsigned int timeout_value_ms){
belle_sip_source_t *s=belle_sip_new0(belle_sip_source_t);
void belle_sip_fd_source_init(belle_sip_source_t *s, belle_sip_source_func_t func, void *data, int fd, unsigned int events, unsigned int timeout_value_ms){
static unsigned long global_id=1;
s->id=global_id++;
s->fd=fd;
s->events=events;
s->timeout=timeout_value_ms;
s->data=data;
s->notify=func;
}
static belle_sip_source_t * belle_sip_fd_source_new(belle_sip_source_func_t func, void *data, int fd, unsigned int events, unsigned int timeout_value_ms){
belle_sip_source_t *s=belle_sip_new0(belle_sip_source_t);
belle_sip_fd_source_init(s,func,data,fd,events,timeout_value_ms);
return s;
}
......@@ -98,10 +93,11 @@ void belle_sip_main_loop_remove_source(belle_sip_main_loop_t *ml, belle_sip_sour
source->on_remove(source);
}
void belle_sip_main_loop_add_timeout(belle_sip_main_loop_t *ml, belle_sip_source_func_t func, void *data, unsigned int timeout_value_ms){
unsigned long belle_sip_main_loop_add_timeout(belle_sip_main_loop_t *ml, belle_sip_source_func_t func, void *data, unsigned int timeout_value_ms){
belle_sip_source_t * s=belle_sip_timeout_source_new(func,data,timeout_value_ms);
s->on_remove=belle_sip_source_destroy;
belle_sip_main_loop_add_source(ml,s);
return s->id;
}
/*
......@@ -206,6 +202,11 @@ void belle_sip_main_loop_quit(belle_sip_main_loop_t *ml){
write(ml->control_fds[1],"a",1);
}
void belle_sip_main_loop_sleep(belle_sip_main_loop_t *ml, int milliseconds){
belle_sip_main_loop_add_timeout(ml,(belle_sip_source_func_t)belle_sip_main_loop_quit,ml,milliseconds);
belle_sip_main_loop_run(ml);
}
void belle_sip_main_loop_destroy(belle_sip_main_loop_t *ml){
belle_sip_main_loop_remove_source (ml,ml->control);
belle_sip_source_destroy(ml->control);
......
/*
belle-sip - SIP (RFC3261) library.
Copyright (C) 2010 Belledonne Communications SARL
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 3 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, see <http://www.gnu.org/licenses/>.
*/
#include "belle_sip_resolver.h"
void belle_sip_resolver_context_destroy(belle_sip_resolver_context_t *ctx){
if (ctx->thread!=0){
if (!ctx->exited){
ctx->cancelled=1;
pthread_cancel(ctx->thread);
}
pthread_join(ctx->thread,NULL);
}
if (ctx->name)
belle_sip_free(ctx->name);
if (ctx->ai){
freeaddrinfo(ctx->ai);
}
belle_sip_free(ctx);
}
static int resolver_callback(belle_sip_resolver_context_t *ctx){
ctx->cb(ctx->cb_data, ctx->name, ctx->ai);
return 0;
}
belle_sip_resolver_context_t *belle_sip_resolver_context_new(){
belle_sip_resolver_context_t *ctx=belle_sip_new0(belle_sip_resolver_context_t);
if (pipe(ctx->ctlpipe)==-1){
belle_sip_fatal("pipe() failed: %s",strerror(errno));
}
belle_sip_fd_source_init(&ctx->source,(belle_sip_source_func_t)resolver_callback,ctx,ctx->ctlpipe[0],BELLE_SIP_EVENT_READ,-1);
ctx->source.on_remove=(belle_sip_source_remove_callback_t)belle_sip_resolver_context_destroy;
return ctx;
}
static void *belle_sip_resolver_thread(void *ptr){
belle_sip_resolver_context_t *ctx=(belle_sip_resolver_context_t *)ptr;
if (write(ctx->ctlpipe[1],"q",1)==-1){
belle_sip_error("belle_sip_resolver_thread(): Fail to write on pipe.");
}
return NULL;
}
unsigned long belle_sip_resolve(const char *name, unsigned int hints, belle_sip_resolver_callback_t cb , void *data, belle_sip_main_loop_t *ml){
belle_sip_resolver_context_t *ctx=belle_sip_resolver_context_new();
ctx->cb_data=data;
ctx->cb=cb;
ctx->name=belle_sip_strdup(name);
ctx->hints=hints;
belle_sip_main_loop_add_source(ml,(belle_sip_source_t*)ctx);
pthread_create(&ctx->thread,NULL,belle_sip_resolver_thread,ctx);
return ctx->source.id;
}
/*
belle-sip - SIP (RFC3261) library.
Copyright (C) 2010 Belledonne Communications SARL
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 3 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef belle_sip_resolver_h
#define belle_sip_resolver_h
#include "belle_sip_internal.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <pthread.h>
#define BELLE_SIP_RESOLVER_HINT_IPV6 (1)
#define BELLE_SIP_RESOLVER_HINT_SRV (1<<1)
typedef struct belle_sip_resolver_context belle_sip_resolver_context_t;
typedef void (*belle_sip_resolver_callback_t)(void *data, const char *name, const struct addrinfo *result);
struct belle_sip_resolver_context{
belle_sip_source_t source;
belle_sip_resolver_callback_t cb;
void *cb_data;
char *name;
struct addrinfo *ai;
unsigned int hints;
pthread_t thread;
int ctlpipe[2];
uint8_t cancelled;
uint8_t exited;
};
unsigned long belle_sip_resolve(const char *name, unsigned int hints, belle_sip_resolver_callback_t cb , void *data, belle_sip_main_loop_t *ml);
#endif
......@@ -403,6 +403,10 @@ void belle_sip_free(void *ptr){
free(ptr);
}
char * belle_sip_strdup(const char *s){
return strdup(s);
}
uint64_t belle_sip_time_ms(void){
struct timespec ts;
static int clock_id=CLOCK_MONOTONIC;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment