void v_print_receive_message(struct vContext *C) { struct IO_CTX *io_ctx = CTX_io_ctx(C); struct VMessage *r_message = CTX_r_message(C); if(is_log_level(VRS_PRINT_DEBUG_MSG)) { printf("%c[%d;%dm", 27, 1, 34); v_print_log(VRS_PRINT_DEBUG_MSG, "Receive message: "); v_print_log_simple(VRS_PRINT_DEBUG_MSG, "Socket: %d, ", io_ctx->sockfd); v_print_addr_port(VRS_PRINT_DEBUG_MSG, &io_ctx->peer_addr); v_print_message_header(VRS_PRINT_DEBUG_MSG, r_message); v_print_log_simple(VRS_PRINT_DEBUG_MSG, "\n"); v_print_message_sys_cmds(VRS_PRINT_DEBUG_MSG, r_message); printf("%c[%dm", 27, 0); } }
void v_print_send_packet(struct vContext *C) { struct IO_CTX *io_ctx = CTX_io_ctx(C); struct VDgramConn *dgram_conn = CTX_current_dgram_conn(C); struct VPacket *s_packet = CTX_s_packet(C); if(is_log_level(VRS_PRINT_DEBUG_MSG)) { printf("%c[%d;%dm", 27, 1, 32); v_print_log(VRS_PRINT_DEBUG_MSG, "Send packet: "); v_print_log_simple(VRS_PRINT_DEBUG_MSG, "Socket: %d, ", io_ctx->sockfd); v_print_addr_port(VRS_PRINT_DEBUG_MSG, &io_ctx->peer_addr); v_print_packet_header(VRS_PRINT_DEBUG_MSG, s_packet); v_print_log(VRS_PRINT_DEBUG_MSG, "Shift: %d -> Window: %d\n", dgram_conn->rwin_host_scale, (unsigned int)s_packet->header.window << dgram_conn->rwin_host_scale); v_print_packet_sys_cmds(VRS_PRINT_DEBUG_MSG, s_packet); printf("%c[%dm", 27, 0); } }
/* Destroy datagram connection */ void v_conn_dgram_destroy(struct VDgramConn *dgram_conn) { /* Debug print */ if(is_log_level(VRS_PRINT_DEBUG_MSG)) { v_print_log(VRS_PRINT_DEBUG_MSG, "Free connection "); v_print_log_simple(VRS_PRINT_DEBUG_MSG, "%d ", dgram_conn->host_id); v_print_addr_port(VRS_PRINT_DEBUG_MSG, &dgram_conn->peer_address); v_print_log_simple(VRS_PRINT_DEBUG_MSG, "\n"); } if(dgram_conn->io_ctx.buf) { free(dgram_conn->io_ctx.buf); dgram_conn->io_ctx.buf = NULL; } v_packet_history_destroy(&dgram_conn->packet_history); v_ack_nak_history_clear(&dgram_conn->ack_nak); close(dgram_conn->io_ctx.sockfd); }
/* Clear datagram connection */ void v_conn_dgram_clear(struct VDgramConn *dgram_conn) { /* Debug print */ if(is_log_level(VRS_PRINT_DEBUG_MSG)) { v_print_log(VRS_PRINT_DEBUG_MSG, "Free connection "); v_print_log_simple(VRS_PRINT_DEBUG_MSG, "%d ", dgram_conn->host_id); v_print_addr_port(VRS_PRINT_DEBUG_MSG, &dgram_conn->peer_address); v_print_log_simple(VRS_PRINT_DEBUG_MSG, "\n"); } #ifdef WITH_OPENSSL if(dgram_conn->io_ctx.bio != NULL) { BIO_vfree(dgram_conn->io_ctx.bio); dgram_conn->io_ctx.bio = NULL; } #endif close(dgram_conn->io_ctx.sockfd); v_conn_dgram_init(dgram_conn); }
/** * \brief This connection tries to handle new connection attempt. When this * attempt is successful, then it creates new thread */ static int vs_new_stream_conn(struct vContext *C, void *(*conn_loop)(void*)) { VS_CTX *vs_ctx = CTX_server_ctx(C); struct IO_CTX *io_ctx = CTX_io_ctx(C); struct VSession *current_session = NULL; socklen_t addr_len; int ret, i; static uint32 last_session_id = 0; /* Try to find free session */ for(i=0; i< vs_ctx->max_sessions; i++) { if(vs_ctx->vsessions[i]->stream_conn->host_state == TCP_SERVER_STATE_LISTEN) { /* TODO: lock mutex here */ current_session = vs_ctx->vsessions[i]; current_session->stream_conn->host_state = TCP_SERVER_STATE_RESPOND_METHODS; current_session->session_id = last_session_id++; /* TODO: unlock mutex here */ break; } } if(current_session != NULL) { struct vContext *new_C; int flag; /* Try to accept client connection (do TCP handshake) */ if(io_ctx->host_addr.ip_ver==IPV4) { /* Prepare IPv4 variables for TCP handshake */ struct sockaddr_in *client_addr4 = ¤t_session->stream_conn->io_ctx.peer_addr.addr.ipv4; current_session->stream_conn->io_ctx.peer_addr.ip_ver = IPV4; addr_len = sizeof(current_session->stream_conn->io_ctx.peer_addr.addr.ipv4); /* Try to do TCP handshake */ if( (current_session->stream_conn->io_ctx.sockfd = accept(io_ctx->sockfd, (struct sockaddr*)client_addr4, &addr_len)) == -1) { if(is_log_level(VRS_PRINT_ERROR)) v_print_log(VRS_PRINT_ERROR, "accept(): %s\n", strerror(errno)); return 0; } /* Save the IPv4 of the client as string in verse session */ inet_ntop(AF_INET, &client_addr4->sin_addr, current_session->peer_hostname, INET_ADDRSTRLEN); } else if(io_ctx->host_addr.ip_ver==IPV6) { /* Prepare IPv6 variables for TCP handshake */ struct sockaddr_in6 *client_addr6 = ¤t_session->stream_conn->io_ctx.peer_addr.addr.ipv6; current_session->stream_conn->io_ctx.peer_addr.ip_ver = IPV6; addr_len = sizeof(current_session->stream_conn->io_ctx.peer_addr.addr.ipv6); /* Try to do TCP handshake */ if( (current_session->stream_conn->io_ctx.sockfd = accept(io_ctx->sockfd, (struct sockaddr*)client_addr6, &addr_len)) == -1) { if(is_log_level(VRS_PRINT_ERROR)) v_print_log(VRS_PRINT_ERROR, "accept(): %s\n", strerror(errno)); return 0; } /* Save the IPv6 of the client as string in verse session */ inet_ntop(AF_INET6, &client_addr6->sin6_addr, current_session->peer_hostname, INET6_ADDRSTRLEN); } /* Set to this socket flag "no delay" */ flag = 1; if(setsockopt(current_session->stream_conn->io_ctx.sockfd, IPPROTO_TCP, TCP_NODELAY, &flag, (socklen_t)sizeof(flag)) == -1) { if(is_log_level(VRS_PRINT_ERROR)) { v_print_log(VRS_PRINT_ERROR, "setsockopt: TCP_NODELAY: %d\n", strerror(errno)); } return -1;; } CTX_current_session_set(C, current_session); CTX_current_stream_conn_set(C, current_session->stream_conn); CTX_io_ctx_set(C, ¤t_session->stream_conn->io_ctx); if(is_log_level(VRS_PRINT_DEBUG_MSG)) { v_print_log(VRS_PRINT_DEBUG_MSG, "New connection from: "); v_print_addr_port(VRS_PRINT_DEBUG_MSG, &(current_session->stream_conn->io_ctx.peer_addr)); v_print_log_simple(VRS_PRINT_DEBUG_MSG, "\n"); } /* Duplicate verse context for new thread */ new_C = (struct vContext*)calloc(1, sizeof(struct vContext)); memcpy(new_C, C, sizeof(struct vContext)); /* Try to initialize thread attributes */ if( (ret = pthread_attr_init(¤t_session->tcp_thread_attr)) !=0 ) { if(is_log_level(VRS_PRINT_ERROR)) v_print_log(VRS_PRINT_ERROR, "pthread_attr_init(): %s\n", strerror(errno)); return 0; } /* Try to set thread attributes as detached */ if( (ret = pthread_attr_setdetachstate(¤t_session->tcp_thread_attr, PTHREAD_CREATE_DETACHED)) != 0) { if(is_log_level(VRS_PRINT_ERROR)) v_print_log(VRS_PRINT_ERROR, "pthread_attr_setdetachstate(): %s\n", strerror(errno)); return 0; } /* Try to create new thread */ if((ret = pthread_create(¤t_session->tcp_thread, ¤t_session->tcp_thread_attr, conn_loop, (void*)new_C)) != 0) { if(is_log_level(VRS_PRINT_ERROR)) v_print_log(VRS_PRINT_ERROR, "pthread_create(): %s\n", strerror(errno)); } /* Destroy thread attributes */ pthread_attr_destroy(¤t_session->tcp_thread_attr); } else { int tmp_sockfd; v_print_log(VRS_PRINT_DEBUG_MSG, "Number of session slot: %d reached\n", vs_ctx->max_sessions); /* TODO: return some error. Not only accept and close connection. */ /* Try to accept client connection (do TCP handshake) */ if(io_ctx->host_addr.ip_ver == IPV4) { /* Prepare IP6 variables for TCP handshake */ struct sockaddr_in client_addr4; addr_len = sizeof(client_addr4); /* Try to do TCP handshake */ if( (tmp_sockfd = accept(io_ctx->sockfd, (struct sockaddr*)&client_addr4, &addr_len)) == -1) { if(is_log_level(VRS_PRINT_ERROR)) v_print_log(VRS_PRINT_ERROR, "accept(): %s\n", strerror(errno)); return 0; } /* Close connection (no more free session slots) */ close(tmp_sockfd); } else if(io_ctx->host_addr.ip_ver == IPV6) { /* Prepare IP6 variables for TCP handshake */ struct sockaddr_in6 client_addr6; addr_len = sizeof(client_addr6); /* Try to do TCP handshake */ if( (tmp_sockfd = accept(io_ctx->sockfd, (struct sockaddr*)&client_addr6, &addr_len)) == -1) { if(is_log_level(VRS_PRINT_ERROR)) v_print_log(VRS_PRINT_ERROR, "accept(): %s\n", strerror(errno)); return 0; } /* Close connection (no more free session slots) */ close(tmp_sockfd); } /* TODO: Fix this */ sleep(1); } return 1; }