Fix race condition issue on TLS connect under centOS

This commit is contained in:
bossiel 2013-03-11 08:37:03 +00:00
parent f2b3f794cc
commit aaa135d14b
12 changed files with 111 additions and 62 deletions

View File

@ -101,7 +101,7 @@ static int tdav_speex_jitterbuffer_put(tmedia_jitterbuffer_t* self, void* data,
jb_packet.data = data;
jb_packet.len = data_size;
jb_packet.span = (data_size*500)/jitterbuffer->rate;
jb_packet.span = (data_size * 500)/jitterbuffer->rate;
jb_packet.timestamp = (rtp_hdr->seq_num * jb_packet.span);
jb_packet.sequence = rtp_hdr->seq_num;

View File

@ -242,6 +242,9 @@ int tnet_tls_socket_recv(tnet_tls_socket_handle_t* self, void** data, tsk_size_t
if(ret == SSL_ERROR_WANT_WRITE || ret == SSL_ERROR_WANT_READ){
ret = 0;
}
else{
TSK_DEBUG_ERROR("SSL_read failed [%d, %s]", ret, ERR_error_string(ERR_get_error(), tsk_null));
}
*size = 0;
}
else{

View File

@ -682,6 +682,7 @@ tnet_fd_t tnet_transport_connectto(const tnet_transport_handle_t *handle, const
struct sockaddr_storage to;
int status = -1;
tnet_fd_t fd = TNET_INVALID_FD;
tnet_tls_socket_handle_t* tls_handle = tsk_null;
if(!transport || !transport->master){
TSK_DEBUG_ERROR("Invalid transport handle");
@ -719,14 +720,6 @@ tnet_fd_t tnet_transport_connectto(const tnet_transport_handle_t *handle, const
TSK_DEBUG_ERROR("Failed to create new sockfd.");
goto bail;
}
/* Add the socket */
if((status = tnet_transport_add_socket(handle, fd, type, tsk_true, tsk_true))){
TNET_PRINT_LAST_ERROR("Failed to add new socket.");
tnet_sockfd_close(&fd);
goto bail;
}
}
else{
fd = transport->master->fd;
@ -740,18 +733,27 @@ tnet_fd_t tnet_transport_connectto(const tnet_transport_handle_t *handle, const
}
else{
if(TNET_SOCKET_TYPE_IS_TLS(type) || TNET_SOCKET_TYPE_IS_WSS(type)){
const tnet_tls_socket_handle_t* tls_handle = tnet_transport_get_tlshandle(handle, fd);
transport->tls.enabled = tsk_true;
if(tls_handle){
/*transport->connected = !*/tnet_tls_socket_connect((tnet_tls_socket_handle_t*)tls_handle);
}
}
else{
//transport->connected = tsk_true;
static const tsk_bool_t __isClient = tsk_true;
static const tsk_bool_t __takeOwnership = tsk_true;
#if HAVE_OPENSSL
tls_handle = tnet_tls_socket_create(fd, transport->tls.ctx_client);
if((status = tnet_tls_socket_connect(tls_handle))){
tnet_sockfd_close(&fd);
goto bail;
}
#endif
/* Add the socket */
// socket must be added after connect() otherwise many Linux systems when return POLLHUP as the fd is not active yet
if((status = tnet_transport_add_socket(handle, fd, type, __takeOwnership, __isClient, tls_handle))){
TNET_PRINT_LAST_ERROR("Failed to add new socket");
tnet_sockfd_close(&fd);
goto bail;
}
}
}
bail:
TSK_OBJECT_SAFE_FREE(tls_handle);
return fd;
}

View File

@ -90,7 +90,7 @@ TINYNET_API int tnet_transport_get_public_ip_n_port(const tnet_transport_handle_
TINYNET_API int tnet_transport_isconnected(const tnet_transport_handle_t *handle, tnet_fd_t fd);
TINYNET_API int tnet_transport_have_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd);
TINYNET_API const tnet_tls_socket_handle_t* tnet_transport_get_tlshandle(const tnet_transport_handle_t *handle, tnet_fd_t fd);
TINYNET_API int tnet_transport_add_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd, tnet_socket_type_t type, tsk_bool_t take_ownership, tsk_bool_t isClient);
TINYNET_API int tnet_transport_add_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd, tnet_socket_type_t type, tsk_bool_t take_ownership, tsk_bool_t isClient, tnet_tls_socket_handle_t* tlsHandle);
TINYNET_API int tnet_transport_pause_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd, tsk_bool_t pause);
TINYNET_API int tnet_transport_remove_socket(const tnet_transport_handle_t *handle, tnet_fd_t* fd);
TINYNET_API tnet_fd_t tnet_transport_connectto(const tnet_transport_handle_t *handle, const char* host, tnet_port_t port, tnet_socket_type_t type);

View File

@ -185,11 +185,12 @@ bail:
return 0;
}
int tnet_transport_add_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd, tnet_socket_type_t type, tsk_bool_t take_ownership, tsk_bool_t isClient)
int tnet_transport_add_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd, tnet_socket_type_t type, tsk_bool_t take_ownership, tsk_bool_t isClient, tnet_tls_socket_handle_t* tlsHandle)
{
tnet_transport_t *transport = (tnet_transport_t*)handle;
transport_context_t* context;
int ret = -1;
(tlsHandle);
if (!transport) {
TSK_DEBUG_ERROR("Invalid server handle.");

View File

@ -71,11 +71,11 @@ typedef struct transport_context_s
transport_context_t;
static transport_socket_xt* getSocket(transport_context_t *context, tnet_fd_t fd);
static int addSocket(tnet_fd_t fd, tnet_socket_type_t type, tnet_transport_t *transport, tsk_bool_t take_ownership, tsk_bool_t is_client);
static int addSocket(tnet_fd_t fd, tnet_socket_type_t type, tnet_transport_t *transport, tsk_bool_t take_ownership, tsk_bool_t is_client, tnet_tls_socket_handle_t* tlsHandle);
static int removeSocket(int index, transport_context_t *context);
int tnet_transport_add_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd, tnet_socket_type_t type, tsk_bool_t take_ownership, tsk_bool_t isClient)
int tnet_transport_add_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd, tnet_socket_type_t type, tsk_bool_t take_ownership, tsk_bool_t isClient, tnet_tls_socket_handle_t* tlsHandle)
{
tnet_transport_t *transport = (tnet_transport_t*)handle;
transport_context_t* context;
@ -96,7 +96,7 @@ int tnet_transport_add_socket(const tnet_transport_handle_t *handle, tnet_fd_t f
transport->tls.enabled = 1;
}
if((ret = addSocket(fd, type, transport, take_ownership, isClient))){
if((ret = addSocket(fd, type, transport, take_ownership, isClient, tlsHandle))){
TSK_DEBUG_ERROR("Failed to add new Socket.");
return ret;
}
@ -295,7 +295,7 @@ static transport_socket_xt* getSocket(transport_context_t *context, tnet_fd_t fd
}
/*== Add new socket ==*/
int addSocket(tnet_fd_t fd, tnet_socket_type_t type, tnet_transport_t *transport, tsk_bool_t take_ownership, tsk_bool_t is_client)
int addSocket(tnet_fd_t fd, tnet_socket_type_t type, tnet_transport_t *transport, tsk_bool_t take_ownership, tsk_bool_t is_client, tnet_tls_socket_handle_t* tlsHandle)
{
transport_context_t *context = transport?transport->context:0;
if(context){
@ -304,10 +304,15 @@ int addSocket(tnet_fd_t fd, tnet_socket_type_t type, tnet_transport_t *transport
sock->type = type;
sock->owner = take_ownership;
if(!sock->tlshandle && (TNET_SOCKET_TYPE_IS_TLS(sock->type) || TNET_SOCKET_TYPE_IS_WSS(sock->type)) && transport->tls.enabled){
if((TNET_SOCKET_TYPE_IS_TLS(sock->type) || TNET_SOCKET_TYPE_IS_WSS(sock->type)) && transport->tls.enabled){
if(tlsHandle){
sock->tlshandle = tsk_object_ref(tlsHandle);
}
else{
#if HAVE_OPENSSL
sock->tlshandle = tnet_tls_socket_create(sock->fd, is_client ? transport->tls.ctx_client : transport->tls.ctx_server);
sock->tlshandle = tnet_tls_socket_create(sock->fd, is_client ? transport->tls.ctx_client : transport->tls.ctx_server);
#endif
}
}
tsk_safeobj_lock(context);
@ -480,7 +485,7 @@ int tnet_transport_prepare(tnet_transport_t *transport)
/* add R side */
TSK_DEBUG_INFO("pipeR fd=%d", context->pipeR);
if((ret = addSocket(context->pipeR, transport->master->type, transport, tsk_true, tsk_false))){
if((ret = addSocket(context->pipeR, transport->master->type, transport, tsk_true, tsk_false, tsk_null))){
goto bail;
}
@ -488,7 +493,7 @@ int tnet_transport_prepare(tnet_transport_t *transport)
TSK_DEBUG_INFO("master fd=%d", transport->master->fd);
// don't take ownership: will be closed by the dctor()
// otherwise will be closed twice: dctor() and removeSocket()
if((ret = addSocket(transport->master->fd, transport->master->type, transport, tsk_false, tsk_false))){
if((ret = addSocket(transport->master->fd, transport->master->type, transport, tsk_false, tsk_false, tsk_null))){
TSK_DEBUG_ERROR("Failed to add master socket");
goto bail;
}
@ -604,12 +609,17 @@ void *tnet_transport_mainthread(void *param)
/*================== TNET_POLLHUP ==================*/
if(context->ufds[i].revents & (TNET_POLLHUP)){
fd = active_socket->fd;
TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- TNET_POLLHUP(%d)", transport->description, fd);
if(context->ufds[i].revents & TNET_POLLOUT){
TSK_DEBUG_INFO("POLLOUT and POLLHUP are exclusive");
}
else{
fd = active_socket->fd;
TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- TNET_POLLHUP(%d)", transport->description, fd);
tnet_transport_remove_socket(transport, &active_socket->fd);
TSK_RUNNABLE_ENQUEUE(transport, event_closed, transport->callback_data, fd);
continue;
tnet_transport_remove_socket(transport, &active_socket->fd);
TSK_RUNNABLE_ENQUEUE(transport, event_closed, transport->callback_data, fd);
continue;
}
}
/*================== TNET_POLLERR ==================*/
@ -673,7 +683,7 @@ void *tnet_transport_mainthread(void *param)
if (listening){
if((fd = accept(active_socket->fd, tsk_null, tsk_null)) != TNET_INVALID_SOCKET){
TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- FD_ACCEPT(fd=%d)", transport->description, fd);
addSocket(fd, transport->master->type, transport, tsk_true, tsk_false);
addSocket(fd, transport->master->type, transport, tsk_true, tsk_false, tsk_null);
TSK_RUNNABLE_ENQUEUE(transport, event_accepted, transport->callback_data, fd);
if(active_socket->tlshandle){
transport_socket_xt* tls_socket;
@ -760,15 +770,18 @@ void *tnet_transport_mainthread(void *param)
// buffer = tsk_realloc(buffer, len);
}
e = tnet_transport_event_create(event_data, transport->callback_data, active_socket->fd);
e->data = buffer;
e->size = len;
e->remote_addr = remote_addr;
if(len > 0){
e = tnet_transport_event_create(event_data, transport->callback_data, active_socket->fd);
e->data = buffer, buffer = tsk_null;
e->size = len;
e->remote_addr = remote_addr;
TSK_RUNNABLE_ENQUEUE_OBJECT_SAFE(TSK_RUNNABLE(transport), e);
TSK_RUNNABLE_ENQUEUE_OBJECT_SAFE(TSK_RUNNABLE(transport), e);
}
TSK_FREE(buffer);
TNET_POLLIN_DONE:
context->ufds[i].revents &= ~TNET_POLLIN;
/*context->ufds[i].revents &= ~TNET_POLLIN*/;
}
@ -779,7 +792,9 @@ TNET_POLLIN_DONE:
active_socket->connected = tsk_true;
TSK_RUNNABLE_ENQUEUE(transport, event_connected, transport->callback_data, active_socket->fd);
}
context->ufds[i].events &= ~TNET_POLLOUT;
//else{
context->ufds[i].events &= ~TNET_POLLOUT;
//}
}

View File

@ -64,7 +64,7 @@ typedef struct transport_context_s
transport_context_t;
static transport_socket_xt* getSocket(transport_context_t *context, tnet_fd_t fd);
static int addSocket(tnet_fd_t fd, tnet_socket_type_t type, tnet_transport_t *transport, tsk_bool_t take_ownership, tsk_bool_t is_client);
static int addSocket(tnet_fd_t fd, tnet_socket_type_t type, tnet_transport_t *transport, tsk_bool_t take_ownership, tsk_bool_t is_client, tnet_tls_socket_handle_t* tlsHandle);
static int removeSocket(int index, transport_context_t *context);
/* Checks if socket is connected */
@ -123,7 +123,7 @@ const tnet_tls_socket_handle_t* tnet_transport_get_tlshandle(const tnet_transpor
/*
* Add new socket to the watcher.
*/
int tnet_transport_add_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd, tnet_socket_type_t type, tsk_bool_t take_ownership, tsk_bool_t isClient)
int tnet_transport_add_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd, tnet_socket_type_t type, tsk_bool_t take_ownership, tsk_bool_t isClient, tnet_tls_socket_handle_t* tlsHandle)
{
tnet_transport_t *transport = (tnet_transport_t*)handle;
transport_context_t* context;
@ -143,7 +143,7 @@ int tnet_transport_add_socket(const tnet_transport_handle_t *handle, tnet_fd_t f
transport->tls.enabled = tsk_true;
}
addSocket(fd, type, transport, take_ownership, isClient);
addSocket(fd, type, transport, take_ownership, isClient, tlsHandle);
if(WSAEventSelect(fd, context->events[context->count - 1], FD_ALL_EVENTS) == SOCKET_ERROR){
removeSocket((context->count - 1), context);
@ -347,7 +347,7 @@ static transport_socket_xt* getSocket(transport_context_t *context, tnet_fd_t fd
}
/*== Add new socket ==*/
static int addSocket(tnet_fd_t fd, tnet_socket_type_t type, tnet_transport_t *transport, tsk_bool_t take_ownership, tsk_bool_t is_client)
static int addSocket(tnet_fd_t fd, tnet_socket_type_t type, tnet_transport_t *transport, tsk_bool_t take_ownership, tsk_bool_t is_client, tnet_tls_socket_handle_t* tlsHandle)
{
transport_context_t *context;
@ -365,9 +365,14 @@ static int addSocket(tnet_fd_t fd, tnet_socket_type_t type, tnet_transport_t *tr
sock->owner = take_ownership ? 1 : 0;
if((TNET_SOCKET_TYPE_IS_TLS(sock->type) || TNET_SOCKET_TYPE_IS_WSS(sock->type)) && transport->tls.enabled){
if(tlsHandle){
sock->tlshandle = tsk_object_ref(tlsHandle);
}
else{
#if HAVE_OPENSSL
sock->tlshandle = tnet_tls_socket_create(sock->fd, is_client ? transport->tls.ctx_client : transport->tls.ctx_server);
sock->tlshandle = tnet_tls_socket_create(sock->fd, is_client ? transport->tls.ctx_client : transport->tls.ctx_server);
#endif
}
}
tsk_safeobj_lock(context);
@ -486,7 +491,7 @@ int tnet_transport_prepare(tnet_transport_t *transport)
/* Add the master socket to the context. */
// don't take ownership: will be closed by the dctor()
// otherwise will be closed twice: dctor() and removeSocket()
if((ret = addSocket(transport->master->fd, transport->master->type, transport, tsk_false, tsk_false))){
if((ret = addSocket(transport->master->fd, transport->master->type, transport, tsk_false, tsk_false, tsk_null))){
TSK_DEBUG_ERROR("Failed to add master socket");
goto bail;
}
@ -595,7 +600,7 @@ void* TSK_STDCALL tnet_transport_mainthread(void *param)
/* Accept the connection */
if((fd = WSAAccept(active_socket->fd, NULL, NULL, AcceptCondFunc, (DWORD_PTR)context)) != INVALID_SOCKET){
/* Add the new fd to the server context */
addSocket(fd, transport->master->type, transport, tsk_true, tsk_false);
addSocket(fd, transport->master->type, transport, tsk_true, tsk_false, tsk_null);
if(active_socket->tlshandle){
transport_socket_xt* tls_socket;
if((tls_socket = getSocket(context, fd))){

View File

@ -1245,7 +1245,7 @@ int trtp_manager_start(trtp_manager_t* self)
/* add RTCP socket to the transport */
if(self->rtcp.local_socket){
if(ret == 0 && (ret = tnet_transport_add_socket(self->transport, self->rtcp.local_socket->fd, self->rtcp.local_socket->type, tsk_false, tsk_true/* only Meaningful for tls*/))){
if(ret == 0 && (ret = tnet_transport_add_socket(self->transport, self->rtcp.local_socket->fd, self->rtcp.local_socket->type, tsk_false, tsk_true/* only Meaningful for tls*/, tsk_null))){
TSK_DEBUG_ERROR("Failed to add RTCP socket");
/* do not exit */
}

View File

@ -143,7 +143,7 @@ int tsip_transport_remove_stream_peer_by_local_fd(tsip_transport_t *self, tnet_f
#define tsip_transport_set_callback(transport, callback, callback_data) (transport ? tnet_transport_set_callback(transport->net_transport, callback, callback_data) : -1)
#define tsip_transport_have_socket(transport, fd) (transport ? tnet_transport_have_socket(transport->net_transport, fd) : 0)
#define tsip_transport_add_socket(transport, fd, type, take_ownership, isClient) (transport ? tnet_transport_add_socket(transport->net_transport, fd, type, take_ownership, isClient) : -1)
#define tsip_transport_add_socket(transport, fd, type, take_ownership, isClient) (transport ? tnet_transport_add_socket(transport->net_transport, fd, type, take_ownership, isClient, tsk_null) : -1)
#define tsip_transport_remove_socket(transport, fd) (transport ? tnet_transport_remove_socket(transport->net_transport, fd) : -1)
//#define tsip_transport_get_socket_type(transport) (transport ? tnet_transport_get_socket_type(transport->net_transport) : tnet_socket_type_invalid)

View File

@ -44,7 +44,8 @@
</div>
<p>
<!-- Obfuscated using: http://womeninbusiness.about.com/gi/o.htm?zi=1/XJ&zTi=1&sdn=womeninbusiness&cdn=money&tm=24&f=10&su=p284.13.342.ip_p554.21.342.ip_&tt=2&bt=1&bts=0&zu=http%3A//www.seowebsitepromotion.com/obfuscate_email.asp -->
For non-technical questions, please <a href="&#109;&#97;&#105;&#108;&#116;&#111;:&#x69;&#x6E;&#x66;&#111;&#64;&#x64;&#111;&#x75;&#x62;&#x61;&#110;&#103;&#x6F;&#x2E;&#111;&#x72;&#x67;?subject=&#73;&#110;&#x66;&#111;&#114;&#109;&#97;&#116;&#x69;&#x6F;&#110;&#32;&#82;&#101;&#x71;&#117;&#101;&#x73;&#116;" title="&#x53;&#x65;&#x6E;&#x64;&#32;&#x75;&#x73;&#32;&#x61;&#32;&#x6D;&#x61;&#105;&#x6C;">&#83;&#x65;&#110;&#x64;&#x20;&#117;&#x73;&#32;&#97;&#x20;&#x6D;&#97;&#105;&#x6C;</a>
For non-technical questions, please <a href="&#109;&#97;&#105;&#108;&#116;&#111;:&#x69;&#x6E;&#x66;&#111;&#64;&#x64;&#111;&#x75;&#x62;&#x61;&#110;&#103;&#x6F;&#x2E;&#111;&#x72;&#x67;?subject=&#73;&#110;&#x66;&#111;&#114;&#109;&#97;&#116;&#x69;&#x6F;&#110;&#32;&#82;&#101;&#x71;&#117;&#101;&#x73;&#116;" title="&#x53;&#x65;&#x6E;&#x64;&#32;&#x75;&#x73;&#32;&#x61;&#32;&#x6D;&#x61;&#105;&#x6C;">&#83;&#x65;&#110;&#x64;&#x20;&#117;&#x73;&#32;&#97;&#x20;&#x6D;&#97;&#105;&#x6C;</a><br />
You can also open <a target=_blank href="http://click2dial.org/u/ZGlvcG1hbWFkb3VAZG91YmFuZ28ub3Jn">this link</a> or press on the green button on the right side to call us on our mobile (or landline) phone.
</p>
<hr />
<p>
@ -85,6 +86,20 @@
&copy; Doubango Telecom 2011-2012</p>
<i>Inspiring the future</i>
</footer>
<!-- click-to-call widget -->
<script type='text/javascript' src='http://click2dial.org/c2c-api.js'></script>
<script type='text/javascript'>
c2c.from = 'ZGlvcG1hbWFkb3VAZG91YmFuZ28ub3Jn';
c2c.text = 'call us &raquo;';
c2c.class = 'btn btn-large btn-success';
c2c.config = {
http_service_url: null,
websocket_proxy_url: null,
sip_outbound_proxy_url: null
};
c2c.init();
</script>
<!-- /container -->
<!-- Le javascript
================================================== -->

View File

@ -270,7 +270,8 @@
</div>
<hr />
<g:plus href="https://plus.google.com/107177632824809995368" rel="author"></g:plus>
<g:plus href="https://plus.google.com/107177632824809995368" rel="author"></g:plus> <br />
<a href="https://twitter.com/DoubangoTelecom" class="twitter-follow-button" data-show-count="false" data-size="large">Follow @DoubangoTelecom</a>
<hr />
<footer>
<p>
@ -307,18 +308,25 @@
var pageTracker = _gat._getTracker("UA-6868621-8");
pageTracker._trackPageview();
} catch (err) { }
</script>
</script>
<!-- click-to-call widget -->
<script type='text/javascript' src='http://click2dial.org/c2c-api.js'></script>
<script type='text/javascript'>
c2c.from = 'ZGlvcG1hbWFkb3VAZG91YmFuZ28ub3Jn';
c2c.text = 'call us &raquo;';
c2c.cls = 'btn btn-large btn-success';
c2c.glass = true;
c2c.config = {
http_service_url: null,
websocket_proxy_url: null,
sip_outbound_proxy_url: null
};
c2c.init();
</script>
<!-- TWITTER -->
<script src='http://www.go2web20.net/twitterfollowbadge/1.0/badge.js' type='text/javascript'></script><script type='text/javascript' charset='utf-8'>
<!--
tfb.account = 'DoubangoTelecom';
tfb.label = 'follow-us';
tfb.color = '#35ccff';
tfb.side = 'r';
tfb.top = 136;
tfb.showbadge();
-->
</script>
<script type='text/javascript'>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
</body>
</html>