Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
BC
public
belle-sip
Commits
f42c9d12
Commit
f42c9d12
authored
Jan 21, 2013
by
Simon Morlat
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
resolver and main loop in progress.
parent
e25a3bdc
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
127 additions
and
52 deletions
+127
-52
include/belle-sip/mainloop.h
include/belle-sip/mainloop.h
+2
-0
include/belle-sip/message.h
include/belle-sip/message.h
+2
-2
include/belle-sip/utils.h
include/belle-sip/utils.h
+2
-0
src/belle_sip_internal.h
src/belle_sip_internal.h
+3
-4
src/belle_sip_loop.c
src/belle_sip_loop.c
+65
-17
src/belle_sip_resolver.c
src/belle_sip_resolver.c
+48
-27
src/belle_sip_resolver.h
src/belle_sip_resolver.h
+5
-2
No files found.
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