int server_socket(void) { struct sockaddr_un sa; int s; TST(strlen(RSTP_SERVER_SOCK_NAME) < sizeof(sa.sun_path), -1); s = socket(PF_UNIX, SOCK_DGRAM, 0); if (s < 0) { ERROR("Couldn't open unix socket: %m"); return -1; } set_socket_address(&sa, RSTP_SERVER_SOCK_NAME); if (bind(s, (struct sockaddr *)&sa, sizeof(sa)) != 0) { ERROR("Couldn't bind socket: %m"); close(s); return -1; } return s; }
int destiny_socket_connect(int socket, sockaddr6_t *addr, uint32_t addrlen) { /* Variables */ ipv6_addr_t src_addr; socket_internal_t *current_int_tcp_socket; socket_t *current_tcp_socket; msg_t msg_from_server; uint8_t send_buffer[BUFFER_SIZE]; ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t *)(&send_buffer)); tcp_hdr_t *current_tcp_packet = ((tcp_hdr_t *)(&send_buffer[IPV6_HDR_LEN])); /* Check if socket exists */ current_int_tcp_socket = get_socket(socket); if (current_int_tcp_socket == NULL) { return -1; } current_tcp_socket = ¤t_int_tcp_socket->socket_values; current_int_tcp_socket->recv_pid = thread_getpid(); /* Local address information */ ipv6_iface_get_best_src_addr(&src_addr, &addr->sin6_addr); set_socket_address(¤t_tcp_socket->local_address, PF_INET6, HTONS(get_free_source_port(IPPROTO_TCP)), 0, &src_addr); /* Foreign address information */ set_socket_address(¤t_tcp_socket->foreign_address, addr->sin6_family, addr->sin6_port, addr->sin6_flowinfo, &addr->sin6_addr); /* Fill lcoal TCP socket information */ srand(addr->sin6_port); current_tcp_socket->tcp_control.rcv_irs = 0; mutex_lock(&global_sequence_clunter_mutex); current_tcp_socket->tcp_control.send_iss = global_sequence_counter; mutex_unlock(&global_sequence_clunter_mutex); current_tcp_socket->tcp_control.state = SYN_SENT; #ifdef TCP_HC /* Choosing random number Context ID */ mutex_lock(&global_context_counter_mutex); current_tcp_socket->tcp_control.tcp_context.context_id = global_context_counter; mutex_unlock(&global_context_counter_mutex); current_tcp_socket->tcp_control.tcp_context.hc_type = FULL_HEADER; /* Remember TCP Context for possible TCP_RETRY */ tcp_hc_context_t saved_tcp_context; memcpy(&saved_tcp_context, ¤t_tcp_socket->tcp_control.tcp_context, sizeof(tcp_hc_context_t)); #endif set_tcp_cb(¤t_tcp_socket->tcp_control, 0, DESTINY_SOCKET_STATIC_WINDOW, current_tcp_socket->tcp_control.send_iss, current_tcp_socket->tcp_control.send_iss, 0); /* Remember current time */ timex_t now; vtimer_now(&now); current_tcp_socket->tcp_control.last_packet_time = now; current_tcp_socket->tcp_control.no_of_retries = 0; msg_from_server.type = TCP_RETRY; while (msg_from_server.type == TCP_RETRY) { /* Send packet */ send_tcp(current_int_tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_SYN, 0); /* wait for SYN ACK or RETRY */ msg_receive(&msg_from_server); if (msg_from_server.type == TCP_TIMEOUT) { #ifdef TCP_HC /* We did not send anything successful so restore last context */ memcpy(¤t_tcp_socket->tcp_control.tcp_context, &saved_tcp_context, sizeof(tcp_hc_context_t)); #endif return -1; } #ifdef TCP_HC else if (msg_from_server.type == TCP_RETRY) { /* We retry sending a packet so set everything to last values again */ memcpy(¤t_tcp_socket->tcp_control.tcp_context, &saved_tcp_context, sizeof(tcp_hc_context_t)); } #endif } /* Read packet content */ tcp_hdr_t *tcp_header = ((tcp_hdr_t *)(msg_from_server.content.ptr)); /* Check for consistency */ if (tcp_header->ack_nr != current_tcp_socket->tcp_control.send_nxt + 1) { printf("TCP packets not consistent!\n"); } /* Got SYN ACK from Server */ /* Refresh foreign TCP socket information */ if ((tcp_header->dataOffset_reserved * 4 > TCP_HDR_LEN) && (*(((uint8_t *)tcp_header) + TCP_HDR_LEN) == TCP_MSS_OPTION)) { current_tcp_socket->tcp_control.mss = *((uint16_t *)(((uint8_t *)tcp_header) + TCP_HDR_LEN + 2)); } else { current_tcp_socket->tcp_control.mss = DESTINY_SOCKET_STATIC_MSS; } current_tcp_socket->tcp_control.rcv_irs = tcp_header->seq_nr; set_tcp_cb(¤t_tcp_socket->tcp_control, tcp_header->seq_nr + 1, current_tcp_socket->tcp_control.rcv_wnd, current_tcp_socket->tcp_control.send_una, current_tcp_socket->tcp_control.send_una, tcp_header->window); current_tcp_socket->tcp_control.send_una++; current_tcp_socket->tcp_control.send_nxt++; msg_from_server.type = UNDEFINED; /* Remember current time */ vtimer_now(&now); current_tcp_socket->tcp_control.last_packet_time = now; current_tcp_socket->tcp_control.no_of_retries = 0; #ifdef TCP_HC current_tcp_socket->tcp_control.tcp_context.hc_type = FULL_HEADER; /* Remember TCP Context for possible TCP_RETRY */ memcpy(&saved_tcp_context, ¤t_tcp_socket->tcp_control.tcp_context, sizeof(tcp_hc_context_t)); #endif while (msg_from_server.type != TCP_RETRY) { /* Send packet */ send_tcp(current_int_tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_ACK, 0); msg_receive(&msg_from_server); #ifdef TCP_HC if (msg_from_server.type == TCP_SYN_ACK) { /* TCP_SYN_ACK from server arrived again, copy old context and * send TCP_ACK again */ memcpy(¤t_tcp_socket->tcp_control.tcp_context, &saved_tcp_context, sizeof(tcp_hc_context_t)); } else if (msg_from_server.type == TCP_RETRY) { /* We waited for RTT, no TCP_SYN_ACK received, so we assume the * TCP_ACK packet arrived safely */ } #endif } current_tcp_socket->tcp_control.state = ESTABLISHED; current_int_tcp_socket->recv_pid = 255; destiny_socket_print_sockets(); return 0; }