Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
belle-sip
Commits
f42c9d12
Commit
f42c9d12
authored
Jan 21, 2013
by
Simon Morlat
Browse files
resolver and main loop in progress.
parent
e25a3bdc
Changes
7
Hide whitespace changes
Inline
Side-by-side
include/belle-sip/mainloop.h
View file @
f42c9d12
...
...
@@ -80,6 +80,8 @@ belle_sip_source_t * belle_sip_socket_source_new(belle_sip_source_func_t func, v
unsigned
long
belle_sip_source_get_id
(
belle_sip_source_t
*
s
);
belle_sip_source_t
*
belle_sip_main_loop_find_source
(
belle_sip_main_loop_t
*
ml
,
unsigned
long
id
);
/**
* Executes the main loop forever (or until belle_sip_main_loop_quit() is called)
**/
...
...
include/belle-sip/message.h
View file @
f42c9d12
...
...
@@ -20,8 +20,8 @@
#define BELLE_SIP_MESSAGE(obj)
BELLE_SIP_CAST(obj,belle_sip_message_t)
#define BELLE_SIP_REQUEST(obj)
BELLE_SIP_CAST(obj,belle_sip_request_t)
#define BELLE_SIP_MESSAGE(obj) BELLE_SIP_CAST(obj,belle_sip_message_t)
#define BELLE_SIP_REQUEST(obj) BELLE_SIP_CAST(obj,belle_sip_request_t)
#define BELLE_SIP_RESPONSE(obj) BELLE_SIP_CAST(obj,belle_sip_response_t)
BELLE_SIP_BEGIN_DECLS
...
...
include/belle-sip/utils.h
View file @
f42c9d12
...
...
@@ -148,8 +148,10 @@ const char* belle_sip_version_to_string();
#include <winsock2.h>
typedef
SOCKET
belle_sip_socket_t
;
typedef
HANDLE
belle_sip_fd_t
;
#else
typedef
int
belle_sip_socket_t
;
typedef
int
belle_sip_fd_t
;
#endif
...
...
src/belle_sip_internal.h
View file @
f42c9d12
...
...
@@ -178,7 +178,7 @@ struct belle_sip_source{
belle_sip_object_t
base
;
belle_sip_list_t
node
;
unsigned
long
id
;
belle_sip_
socket
_t
fd
;
belle_sip_
fd
_t
fd
;
unsigned
int
events
;
int
timeout
;
void
*
data
;
...
...
@@ -188,12 +188,11 @@ struct belle_sip_source{
belle_sip_source_remove_callback_t
on_remove
;
unsigned
char
cancelled
;
unsigned
char
expired
;
#ifdef WIN32
WSAEVENT
wsaevent
;
#endif
belle_sip_socket_t
sock
;
};
void
belle_sip_socket_source_init
(
belle_sip_source_t
*
s
,
belle_sip_source_func_t
func
,
void
*
data
,
belle_sip_socket_t
fd
,
unsigned
int
events
,
unsigned
int
timeout_value_ms
);
void
belle_sip_fd_source_init
(
belle_sip_source_t
*
s
,
belle_sip_source_func_t
func
,
void
*
data
,
belle_sip_fd_t
fd
,
unsigned
int
events
,
unsigned
int
timeout_value_ms
);
#define belle_list_next(elem) ((elem)->next)
/* include private headers */
...
...
src/belle_sip_loop.c
View file @
f42c9d12
...
...
@@ -77,12 +77,35 @@ static unsigned int belle_sip_source_get_revents(belle_sip_source_t *s,belle_sip
typedef
HANDLE
belle_sip_pollfd_t
;
static
void
belle_sip_source_to_poll
(
belle_sip_source_t
*
s
,
belle_sip_pollfd_t
*
pfd
,
int
i
){
pfd
[
i
]
=
s
->
wsaevent
;
int
err
;
long
events
=
0
;
pfd
[
i
]
=
s
->
fd
;
s
->
index
=
i
;
if
(
s
->
events
&
BELLE_SIP_EVENT_READ
)
events
|=
FD_READ
;
if
(
s
->
events
&
BELLE_SIP_EVENT_WRITE
)
events
|=
FD_WRITE
;
err
=
WSAEventSelect
(
s
->
sock
,
s
->
fd
,
events
);
if
(
err
!=
0
)
belle_sip_error
(
"WSAEventSelect() failed: %i"
,
err
);
}
static
unsigned
int
belle_sip_source_get_revents
(
belle_sip_source_t
*
s
,
belle_sip_pollfd_t
*
pfd
){
return
0
;
WSANETWORKEVENTS
revents
=
{
0
};
int
err
;
unsigned
int
ret
=
0
;
err
=
WSAEnumNetworkEvents
(
s
->
sock
,
NULL
,
&
revents
);
if
(
err
!=
0
){
belle_sip_error
(
"WSAEnumNetworkEvents() failed: %i"
,
err
);
return
0
;
}
if
(
revents
.
lNetworkEvents
&
FD_READ
)
ret
|=
BELLE_SIP_EVENT_READ
;
if
(
revents
.
lNetworkEvents
&
FD_WRITE
)
ret
|=
BELLE_SIP_EVENT_WRITE
;
return
ret
;
}
static
int
belle_sip_poll
(
belle_sip_pollfd_t
*
pfd
,
int
count
,
int
duration
){
...
...
@@ -104,14 +127,14 @@ static void belle_sip_source_destroy(belle_sip_source_t *obj){
belle_sip_fatal
(
"Destroying source currently used in main loop !"
);
}
#ifdef WIN32
if
(
obj
->
wsaevent
!=
(
WSAEVENT
)
-
1
){
WSACloseEvent
(
obj
->
wsaevent
);
obj
->
wsaevent
=
(
WSAEVENT
)
-
1
;
if
(
obj
->
sock
!=
(
belle_sip_socket_t
)
-
1
){
WSACloseEvent
(
obj
->
fd
);
obj
->
fd
=
(
WSAEVENT
)
-
1
;
}
#endif
}
void
belle_sip_
socket_
source_init
(
belle_sip_source_t
*
s
,
belle_sip_source_func_t
func
,
void
*
data
,
belle_sip_
socket
_t
fd
,
unsigned
int
events
,
unsigned
int
timeout_value_ms
){
static
void
belle_sip_source_init
(
belle_sip_source_t
*
s
,
belle_sip_source_func_t
func
,
void
*
data
,
belle_sip_
fd
_t
fd
,
unsigned
int
events
,
unsigned
int
timeout_value_ms
){
static
unsigned
long
global_id
=
1
;
s
->
node
.
data
=
s
;
s
->
id
=
global_id
++
;
...
...
@@ -120,20 +143,40 @@ void belle_sip_socket_source_init(belle_sip_source_t *s, belle_sip_source_func_t
s
->
timeout
=
timeout_value_ms
;
s
->
data
=
data
;
s
->
notify
=
func
;
}
void
belle_sip_socket_source_init
(
belle_sip_source_t
*
s
,
belle_sip_source_func_t
func
,
void
*
data
,
belle_sip_socket_t
sock
,
unsigned
int
events
,
unsigned
int
timeout_value_ms
){
s
->
sock
=
sock
;
#ifdef WIN32
if
(
fd
!=
(
belle_sip_socket_t
)
-
1
)
s
->
wsaevent
=
WSACreateEvent
();
/*on windows, the fd to poll is not the socket */
belle_sip_fd_t
fd
=
(
belle_sip_fd_t
)
-
1
;
if
(
sock
!=
(
belle_sip_socket_t
)
-
1
)
fd
=
WSACreateEvent
();
else
s
->
wsaevent
=
(
WSAEVENT
)
-
1
;
fd
=
(
WSAEVENT
)
-
1
;
belle_sip_source_init
(
s
,
func
,
data
,
fd
,
events
,
timeout_value_ms
);
#else
belle_sip_source_init
(
s
,
func
,
data
,
sock
,
events
,
timeout_value_ms
);
#endif
}
void
belle_sip_fd_source_init
(
belle_sip_source_t
*
s
,
belle_sip_source_func_t
func
,
void
*
data
,
belle_sip_fd_t
fd
,
unsigned
int
events
,
unsigned
int
timeout_value_ms
){
belle_sip_source_init
(
s
,
func
,
data
,
fd
,
events
,
timeout_value_ms
);
}
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES
(
belle_sip_source_t
);
BELLE_SIP_INSTANCIATE_VPTR
(
belle_sip_source_t
,
belle_sip_object_t
,
belle_sip_source_destroy
,
NULL
,
NULL
,
FALSE
);
belle_sip_source_t
*
belle_sip_socket_source_new
(
belle_sip_source_func_t
func
,
void
*
data
,
belle_sip_socket_t
fd
,
unsigned
int
events
,
unsigned
int
timeout_value_ms
){
belle_sip_source_t
*
belle_sip_socket_source_new
(
belle_sip_source_func_t
func
,
void
*
data
,
belle_sip_socket_t
sock
,
unsigned
int
events
,
unsigned
int
timeout_value_ms
){
belle_sip_source_t
*
s
=
belle_sip_object_new
(
belle_sip_source_t
);
belle_sip_socket_source_init
(
s
,
func
,
data
,
fd
,
events
,
timeout_value_ms
);
belle_sip_socket_source_init
(
s
,
func
,
data
,
sock
,
events
,
timeout_value_ms
);
return
s
;
}
belle_sip_source_t
*
belle_sip_fd_source_new
(
belle_sip_source_func_t
func
,
void
*
data
,
belle_sip_fd_t
fd
,
unsigned
int
events
,
unsigned
int
timeout_value_ms
){
belle_sip_source_t
*
s
=
belle_sip_object_new
(
belle_sip_source_t
);
belle_sip_fd_source_init
(
s
,
func
,
data
,
fd
,
events
,
timeout_value_ms
);
return
s
;
}
...
...
@@ -151,7 +194,7 @@ int belle_sip_source_set_events(belle_sip_source_t* source, int event_mask) {
}
belle_sip_socket_t
belle_sip_source_get_socket
(
const
belle_sip_source_t
*
source
)
{
return
source
->
fd
;
return
source
->
sock
;
}
...
...
@@ -230,12 +273,17 @@ static int match_source_id(const void *s, const void *pid){
return
-
1
;
}
void
belle_sip_main_loop_
cancel
_source
(
belle_sip_main_loop_t
*
ml
,
unsigned
long
id
){
belle_sip_source_t
*
belle_sip_main_loop_
find
_source
(
belle_sip_main_loop_t
*
ml
,
unsigned
long
id
){
belle_sip_list_t
*
elem
=
belle_sip_list_find_custom
(
ml
->
sources
,
match_source_id
,(
const
void
*
)
id
);
if
(
elem
!=
NULL
){
belle_sip_source_t
*
s
=
(
belle_sip_source_t
*
)
elem
->
data
;
s
->
cancelled
=
TRUE
;
return
(
belle_sip_source_t
*
)
elem
->
data
;
}
return
NULL
;
}
void
belle_sip_main_loop_cancel_source
(
belle_sip_main_loop_t
*
ml
,
unsigned
long
id
){
belle_sip_source_t
*
s
=
belle_sip_main_loop_find_source
(
ml
,
id
);
if
(
s
)
s
->
cancelled
=
TRUE
;
}
void
belle_sip_main_loop_iterate
(
belle_sip_main_loop_t
*
ml
){
...
...
@@ -254,7 +302,7 @@ void belle_sip_main_loop_iterate(belle_sip_main_loop_t *ml){
next
=
elem
->
next
;
s
=
(
belle_sip_source_t
*
)
elem
->
data
;
if
(
!
s
->
cancelled
){
if
(
s
->
fd
!=
(
belle_sip_
socket
_t
)
-
1
){
if
(
s
->
fd
!=
(
belle_sip_
fd
_t
)
-
1
){
belle_sip_source_to_poll
(
s
,
pfd
,
i
);
++
i
;
}
...
...
@@ -288,7 +336,7 @@ void belle_sip_main_loop_iterate(belle_sip_main_loop_t *ml){
s
=
(
belle_sip_source_t
*
)
elem
->
data
;
if
(
!
s
->
cancelled
){
if
(
s
->
fd
!=
(
belle_sip_
socket
_t
)
-
1
){
if
(
s
->
fd
!=
(
belle_sip_
fd
_t
)
-
1
){
revents
=
belle_sip_source_get_revents
(
s
,
pfd
);
}
if
(
revents
!=
0
||
(
s
->
timeout
>=
0
&&
cur
>=
s
->
expire_ms
)){
...
...
src/belle_sip_resolver.c
View file @
f42c9d12
...
...
@@ -47,12 +47,8 @@ struct addrinfo * belle_sip_ip_address_to_addrinfo(const char *ipaddress, int po
}
void
belle_sip_resolver_context_destroy
(
belle_sip_resolver_context_t
*
ctx
){
static
void
belle_sip_resolver_context_destroy
(
belle_sip_resolver_context_t
*
ctx
){
if
(
ctx
->
thread
!=
0
){
if
(
!
ctx
->
exited
){
ctx
->
cancelled
=
1
;
belle_sip_thread_cancel
(
ctx
->
thread
);
}
belle_sip_thread_join
(
ctx
->
thread
,
NULL
);
}
if
(
ctx
->
name
)
...
...
@@ -63,8 +59,6 @@ void belle_sip_resolver_context_destroy(belle_sip_resolver_context_t *ctx){
#ifndef WIN32
close
(
ctx
->
ctlpipe
[
0
]);
close
(
ctx
->
ctlpipe
[
1
]);
#else
CloseEvent
(
ctx
->
ctlevent
);
#endif
}
...
...
@@ -72,27 +66,25 @@ BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_resolver_context_t);
BELLE_SIP_INSTANCIATE_VPTR
(
belle_sip_resolver_context_t
,
belle_sip_source_t
,
belle_sip_resolver_context_destroy
,
NULL
,
NULL
,
FALSE
);
static
int
resolver_callback
(
belle_sip_resolver_context_t
*
ctx
){
char
tmp
;
ctx
->
cb
(
ctx
->
cb_data
,
ctx
->
name
,
ctx
->
ai
);
ctx
->
ai
=
NULL
;
belle_sip_message
(
"resolver_callback() for %s called."
,
ctx
->
name
);
if
(
!
ctx
->
cancelled
){
ctx
->
cb
(
ctx
->
cb_data
,
ctx
->
name
,
ctx
->
ai
);
ctx
->
ai
=
NULL
;
}
#ifndef WIN32
if
(
read
(
ctx
->
source
.
fd
,
&
tmp
,
1
)
!=
1
){
belle_sip_fatal
(
"Unexpected read from resolver_callback"
);
{
char
tmp
;
if
(
read
(
ctx
->
source
.
fd
,
&
tmp
,
1
)
!=
1
){
belle_sip_fatal
(
"Unexpected read from resolver_callback"
);
}
}
#else
#endif
/*by returning stop, we'll be removed from main loop and destroyed. */
return
BELLE_SIP_STOP
;
}
belle_sip_resolver_context_t
*
belle_sip_resolver_context_new
(){
belle_sip_resolver_context_t
*
ctx
=
belle_sip_object_new
(
belle_sip_resolver_context_t
);
#ifndef WIN32
if
(
pipe
(
ctx
->
ctlpipe
)
==-
1
){
belle_sip_fatal
(
"pipe() failed: %s"
,
strerror
(
errno
));
}
#else
#endif
belle_sip_fd_source_init
(
&
ctx
->
source
,(
belle_sip_source_func_t
)
resolver_callback
,
ctx
,
ctx
->
ctlpipe
[
0
],
BELLE_SIP_EVENT_READ
,
-
1
);
return
ctx
;
}
...
...
@@ -103,9 +95,12 @@ static void *belle_sip_resolver_thread(void *ptr){
char
serv
[
10
];
int
err
;
/*the thread owns a ref on the resolver context*/
belle_sip_object_ref
(
ctx
);
belle_sip_message
(
"Resolver thread started."
);
snprintf
(
serv
,
sizeof
(
serv
),
"%i"
,
ctx
->
port
);
hints
.
ai_family
=
(
ctx
->
hints
&
BELLE_SIP_RESOLVER_HINT_IPV6
)
?
AF_INET6
:
AF_INET
;
hints
.
ai_family
=
ctx
->
family
;
hints
.
ai_flags
=
AI_NUMERICSERV
;
err
=
getaddrinfo
(
ctx
->
name
,
serv
,
&
hints
,
&
res
);
if
(
err
!=
0
){
...
...
@@ -120,13 +115,26 @@ static void *belle_sip_resolver_thread(void *ptr){
if
(
write
(
ctx
->
ctlpipe
[
1
],
"q"
,
1
)
==-
1
){
belle_sip_error
(
"belle_sip_resolver_thread(): Fail to write on pipe."
);
}
#else
SetEvent
(
ctx
->
ctlevent
);
#endif
belle_sip_object_unref
(
ctx
);
return
NULL
;
}
unsigned
long
belle_sip_resolve
(
const
char
*
name
,
int
port
,
unsigned
int
hints
,
belle_sip_resolver_callback_t
cb
,
void
*
data
,
belle_sip_main_loop_t
*
ml
){
static
void
belle_sip_resolver_context_start
(
belle_sip_resolver_context_t
*
ctx
){
belle_sip_fd_t
fd
=
(
belle_sip_fd_t
)
-
1
;
belle_sip_thread_create
(
&
ctx
->
thread
,
NULL
,
belle_sip_resolver_thread
,
ctx
);
#ifndef WIN32
if
(
pipe
(
ctx
->
ctlpipe
)
==-
1
){
belle_sip_fatal
(
"pipe() failed: %s"
,
strerror
(
errno
));
}
fd
=
ctx
->
ctlpipe
[
0
];
#else
fd
=
(
HANDLE
)
ctx
->
thread
;
#endif
belle_sip_fd_source_init
(
&
ctx
->
source
,(
belle_sip_source_func_t
)
resolver_callback
,
ctx
,
fd
,
BELLE_SIP_EVENT_READ
,
-
1
);
}
unsigned
long
belle_sip_resolve
(
const
char
*
name
,
int
port
,
int
family
,
belle_sip_resolver_callback_t
cb
,
void
*
data
,
belle_sip_main_loop_t
*
ml
){
struct
addrinfo
*
res
=
belle_sip_ip_address_to_addrinfo
(
name
,
port
);
if
(
res
==
NULL
){
/*then perform asynchronous DNS query */
...
...
@@ -135,10 +143,13 @@ unsigned long belle_sip_resolve(const char *name, int port, unsigned int hints,
ctx
->
cb
=
cb
;
ctx
->
name
=
belle_sip_strdup
(
name
);
ctx
->
port
=
port
;
ctx
->
hints
=
hints
;
if
(
family
==
0
)
family
=
AF_UNSPEC
;
ctx
->
family
=
family
;
belle_sip_resolver_context_start
(
ctx
);
/*the resolver context must never be removed manually from the main loop*/
belle_sip_main_loop_add_source
(
ml
,(
belle_sip_source_t
*
)
ctx
);
belle_sip_object_unref
(
ctx
);
belle_sip_thread_create
(
&
ctx
->
thread
,
NULL
,
belle_sip_resolver_thread
,
ctx
);
belle_sip_object_unref
(
ctx
);
/*the main loop and the thread have a ref on it*/
return
ctx
->
source
.
id
;
}
else
{
cb
(
data
,
name
,
res
);
...
...
@@ -146,6 +157,16 @@ unsigned long belle_sip_resolve(const char *name, int port, unsigned int hints,
}
}
void
belle_sip_resolve_cancel
(
belle_sip_main_loop_t
*
ml
,
unsigned
long
id
){
if
(
id
!=
0
){
belle_sip_source_t
*
s
=
belle_sip_main_loop_find_source
(
ml
,
id
);
if
(
s
){
belle_sip_resolver_context_t
*
res
=
BELLE_SIP_RESOLVER_CONTEXT
(
s
);
res
->
cancelled
=
1
;
}
}
}
void
belle_sip_get_src_addr_for
(
const
struct
sockaddr
*
dest
,
socklen_t
destlen
,
struct
sockaddr
*
src
,
socklen_t
*
srclen
){
int
af_type
=
(
destlen
==
sizeof
(
struct
sockaddr_in6
))
?
AF_INET6
:
AF_INET
;
int
sock
=
socket
(
af_type
,
SOCK_DGRAM
,
IPPROTO_UDP
);
...
...
src/belle_sip_resolver.h
View file @
f42c9d12
...
...
@@ -25,6 +25,8 @@
typedef
struct
belle_sip_resolver_context
belle_sip_resolver_context_t
;
#define BELLE_SIP_RESOLVER_CONTEXT(obj) BELLE_SIP_CAST(obj,belle_sip_resolver_context_t)
/**
* Callback prototype for asynchronous DNS resolution. The result addrinfo must be taken and (possibly later) freed by
* the callee, using freeaddrinfo().
...
...
@@ -39,7 +41,7 @@ struct belle_sip_resolver_context{
char
*
name
;
int
port
;
struct
addrinfo
*
ai
;
unsigned
int
hints
;
int
family
;
belle_sip_thread_t
thread
;
#ifndef WIN32
int
ctlpipe
[
2
];
...
...
@@ -51,7 +53,8 @@ struct belle_sip_resolver_context{
};
struct
addrinfo
*
belle_sip_ip_address_to_addrinfo
(
const
char
*
ipaddress
,
int
port
);
unsigned
long
belle_sip_resolve
(
const
char
*
name
,
int
port
,
unsigned
int
hints
,
belle_sip_resolver_callback_t
cb
,
void
*
data
,
belle_sip_main_loop_t
*
ml
);
unsigned
long
belle_sip_resolve
(
const
char
*
name
,
int
port
,
int
family
,
belle_sip_resolver_callback_t
cb
,
void
*
data
,
belle_sip_main_loop_t
*
ml
);
void
belle_sip_resolve_cancel
(
belle_sip_main_loop_t
*
ml
,
unsigned
long
id
);
void
belle_sip_get_src_addr_for
(
const
struct
sockaddr
*
dest
,
socklen_t
destlen
,
struct
sockaddr
*
src
,
socklen_t
*
srclen
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment