void v_destroy_session(struct VSession *vsession) { vsession->tcp_thread = 0; vsession->udp_thread = 0; if(vsession->dgram_conn != NULL) { v_conn_dgram_destroy(vsession->dgram_conn); free(vsession->dgram_conn); vsession->dgram_conn = NULL; } if(vsession->stream_conn != NULL) { v_conn_stream_destroy(vsession->stream_conn); free(vsession->stream_conn); vsession->stream_conn = NULL; } if(vsession->peer_hostname != NULL) { free(vsession->peer_hostname); vsession->peer_hostname = NULL; } if(vsession->ded.str != NULL) { free(vsession->ded.str); vsession->ded.str = NULL; } if(vsession->service != NULL) { free(vsession->service); vsession->service = NULL; } if(vsession->in_queue != NULL) { v_in_queue_destroy(&vsession->in_queue); } if(vsession->out_queue != NULL) { v_out_queue_destroy(&vsession->out_queue); } if(vsession->host_url != NULL) { free(vsession->host_url); vsession->host_url = NULL; } if(vsession->peer_cookie.str != NULL) { free(vsession->peer_cookie.str); vsession->peer_cookie.str = NULL; } if(vsession->host_cookie.str != NULL) { free(vsession->host_cookie.str); vsession->host_cookie.str = NULL; } if(vsession->client_name != NULL) { free(vsession->client_name); vsession->client_name = NULL; } if(vsession->client_version != NULL) { free(vsession->client_version); vsession->client_version = NULL; } }
void* vc_main_dgram_loop(void *arg) { struct vContext *C = (struct vContext*)arg; struct VSession *vsession = CTX_current_session(C); struct VDgramConn *dgram_conn = vsession->dgram_conn; struct VStreamConn *stream_conn = CTX_current_stream_conn(C); struct VPacket *r_packet, *s_packet; char error = 0; const uint8 *ret_val = 0; if(dgram_conn==NULL) { /* Create new datagrame connection */ if((dgram_conn = vc_create_client_dgram_conn(C))==NULL) { goto finish; } vsession->dgram_conn = dgram_conn; } CTX_current_dgram_conn_set(C, dgram_conn); CTX_io_ctx_set(C, &dgram_conn->io_ctx); #if (defined WITH_OPENSSL) && OPENSSL_VERSION_NUMBER>=0x10000000 /* If negotiated security is DTLS, then try to do DTLS handshake */ if(dgram_conn->io_ctx.flags & SOCKET_SECURED) { if(vc_create_dtls_connection(C) == 0) { CTX_current_dgram_conn_set(C, NULL); CTX_io_ctx_set(C, NULL); free(dgram_conn); ret_val = &vrs_conn_term_error; goto finish; } } #endif /* Packet structure for receiving */ r_packet = (struct VPacket*)malloc(sizeof(struct VPacket)); CTX_r_packet_set(C, r_packet); /* Packet structure for sending */ s_packet = (struct VPacket*)malloc(sizeof(struct VPacket)); CTX_s_packet_set(C, s_packet); /* Run loop of the first phase of the handshake */ if((error = vc_REQUEST_loop(C)) == STATE_EXIT_ERROR) { /* Do not confirm proposed URL, when client was not able to connect * to the server */ CTX_io_ctx_set(C, &stream_conn->io_ctx); vc_NEGOTIATE_newhost(C, NULL); CTX_io_ctx_set(C, &dgram_conn->io_ctx); ret_val = &vrs_conn_term_error; goto end; } /* When server responded in the first phase of the handshake, then run loop of the second * phase of the handshake */ if((error = vc_PARTOPEN_loop(C)) == STATE_EXIT_ERROR) { /* Do not confirm proposed URL, when client was not able to connect * to the server */ CTX_io_ctx_set(C, &stream_conn->io_ctx); vc_NEGOTIATE_newhost(C, NULL); CTX_io_ctx_set(C, &dgram_conn->io_ctx); ret_val = &vrs_conn_term_error; goto end; } else { struct Connect_Accept_Cmd *conn_accept; /* Put connect accept command to queue -> call callback function */ conn_accept = v_Connect_Accept_create(vsession->avatar_id, vsession->user_id); v_in_queue_push(vsession->in_queue, (struct Generic_Cmd*)conn_accept); /* Send confirmation of the URL to the server */ CTX_io_ctx_set(C, &stream_conn->io_ctx); vc_NEGOTIATE_newhost(C, vsession->host_url); CTX_io_ctx_set(C, &dgram_conn->io_ctx); /* TCP connection could be closed now */ vsession->stream_conn->host_state = TCP_CLIENT_STATE_CLOSING; } /* Main loop for data exchange */ if((error = vc_OPEN_loop(C)) == STATE_EXIT_ERROR) { ret_val = &vrs_conn_term_error; goto end; } /* Closing loop */ if((error = vc_CLOSING_loop(C)) == STATE_EXIT_ERROR) { ret_val = &vrs_conn_term_error; goto end; } /* TODO: distinguish between terminating connection by server and client */ ret_val = &vrs_conn_term_server; end: /* CLOSED state */ if(is_log_level(VRS_PRINT_DEBUG_MSG)) { printf("%c[%d;%dm", 27, 1, 31); v_print_log(VRS_PRINT_DEBUG_MSG, "Client state: CLOSED\n"); printf("%c[%dm", 27, 0); } free(r_packet); free(s_packet); #if (defined WITH_OPENSSL) && OPENSSL_VERSION_NUMBER>=0x10000000 if(dgram_conn->io_ctx.flags & SOCKET_SECURED) { vc_destroy_dtls_connection(C); } #endif v_conn_dgram_destroy(dgram_conn); CTX_current_dgram_conn_set(C, NULL); finish: pthread_exit((void*)ret_val); return NULL; }