Esempio n. 1
0
int destiny_socket_close(int s)
{
    socket_internal_t *current_socket = get_socket(s);

    if (current_socket != NULL) {
        if (is_tcp_socket(s)) {
            /* Variables */
            msg_t m_recv;
            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 and is TCP socket */
            if (!is_tcp_socket(s)) {
                return -1;
            }

            /* Check for ESTABLISHED STATE */
            if (current_socket->socket_values.tcp_control.state != ESTABLISHED) {
                close_socket(current_socket);
                return 0;
            }

            current_socket->send_pid = thread_getpid();

            /* Refresh local TCP socket information */
            current_socket->socket_values.tcp_control.send_una++;
            current_socket->socket_values.tcp_control.state = FIN_WAIT_1;
#ifdef TCP_HC
            current_socket->socket_values.tcp_control.tcp_context.hc_type =
                COMPRESSED_HEADER;
#endif

            send_tcp(current_socket, current_tcp_packet, temp_ipv6_header,
                     TCP_FIN, 0);
            msg_receive(&m_recv);
            close_socket(current_socket);
            return 1;
        }
        else if (isUDPSocket(s)) {
            close_socket(current_socket);
            return 0;
        }

        return -1;
    }
    else {
        return -1;
    }
}
Esempio n. 2
0
void check_sockets(void)
{
    socket_internal_t *current_socket;
    uint8_t i = 1;

    while (i < MAX_SOCKETS + 1) {
        current_socket = get_socket(i);

        if (is_tcp_socket(i)) {
            switch (current_socket->socket_values.tcp_control.state) {
                case ESTABLISHED: {
                    handle_established(current_socket);
                    break;
                }

                case SYN_SENT: {
                    handle_synchro_timeout(current_socket);
                    break;
                }

                case SYN_RCVD: {
                    handle_synchro_timeout(current_socket);
                    break;
                }

                default: {
                    break;
                }
            }
        }

        i++;
    }
}
Esempio n. 3
0
int32_t destiny_socket_recvfrom(int s, void *buf, uint32_t len, int flags,
                                sockaddr6_t *from, uint32_t *fromlen)
{
    if (isUDPSocket(s)) {
        msg_t m_recv, m_send;
        ipv6_hdr_t *ipv6_header;
        udp_hdr_t *udp_header;
        uint8_t *payload;
        get_socket(s)->recv_pid = thread_getpid();

        msg_receive(&m_recv);

        ipv6_header = ((ipv6_hdr_t *)m_recv.content.ptr);
        udp_header = ((udp_hdr_t *)(m_recv.content.ptr + IPV6_HDR_LEN));
        payload = (uint8_t *)(m_recv.content.ptr + IPV6_HDR_LEN + UDP_HDR_LEN);

        memset(buf, 0, len);
        memcpy(buf, payload, udp_header->length - UDP_HDR_LEN);
        memcpy(&from->sin6_addr, &ipv6_header->srcaddr, 16);
        from->sin6_family = AF_INET6;
        from->sin6_flowinfo = 0;
        from->sin6_port = udp_header->src_port;
        *fromlen = sizeof(sockaddr6_t);

        msg_reply(&m_recv, &m_send);
        return udp_header->length - UDP_HDR_LEN;
    }
    else if (is_tcp_socket(s)) {
        return destiny_socket_recv(s, buf, len, flags);
    }
    else {
        printf("Socket Type not supported!\n");
        return -1;
    }
}
Esempio n. 4
0
int destiny_socket_accept(int s, sockaddr6_t *addr, uint32_t *addrlen)
{
    socket_internal_t *server_socket = get_socket(s);

    if (is_tcp_socket(s) && (server_socket->socket_values.tcp_control.state == LISTEN)) {
        socket_internal_t *current_queued_socket =
            get_waiting_connection_socket(s, NULL, NULL);

        if (current_queued_socket != NULL) {
            return handle_new_tcp_connection(current_queued_socket,
                                             server_socket, thread_getpid());
        }
        else {
            /* No waiting connections, waiting for message from TCP Layer */
            msg_t msg_recv_client_syn;
            msg_recv_client_syn.type = UNDEFINED;

            while (msg_recv_client_syn.type != TCP_SYN) {
                msg_receive(&msg_recv_client_syn);
            }

            current_queued_socket = get_waiting_connection_socket(s, NULL, NULL);

            return handle_new_tcp_connection(current_queued_socket,
                                             server_socket, thread_getpid());
        }
    }
    else {
        return -1;
    }
}
Esempio n. 5
0
int destiny_socket_listen(int s, int backlog)
{
    if (is_tcp_socket(s) && get_socket(s)->socket_values.tcp_control.state == CLOSED) {
        socket_internal_t *current_socket = get_socket(s);
        current_socket->socket_values.tcp_control.state = LISTEN;
        return 0;
    }
    else {
        return -1;
    }
}
Esempio n. 6
0
socket_internal_t *get_tcp_socket(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header)
{
    uint8_t i = 1;
    socket_internal_t *current_socket = NULL;
    socket_internal_t *listening_socket = NULL;
    uint8_t compare[16];
    memset(compare, 0, 16);

    while (i < MAX_SOCKETS + 1) {
        current_socket = get_socket(i);

        /* Check for matching 4 touple, ESTABLISHED connection */
        if (is_tcp_socket(i) && is_four_touple(current_socket, ipv6_header,
                                               tcp_header)) {
            return current_socket;
        }
        /* Sockets in LISTEN and SYN_RCVD state should only be tested on local TCP values */
        else if (is_tcp_socket(i) &&
                 ((current_socket->socket_values.tcp_control.state == LISTEN) ||
                  (current_socket->socket_values.tcp_control.state == SYN_RCVD)) &&
                 (current_socket->socket_values.local_address.sin6_addr.uint8[15] ==
                  ipv6_header->destaddr.uint8[15]) &&
                 (current_socket->socket_values.local_address.sin6_port ==
                  tcp_header->dst_port) &&
                 (current_socket->socket_values.foreign_address.sin6_addr.uint8[15] ==
                  0x00) &&
                 (current_socket->socket_values.foreign_address.sin6_port == 0)) {
            listening_socket = current_socket;
        }

        i++;
    }

    /* Return either NULL if nothing was matched or the listening 2 touple socket */
    return listening_socket;
}
Esempio n. 7
0
int bind_tcp_socket(int s, sockaddr6_t *name, int namelen, uint8_t pid)
{
    int i;

    if (!exists_socket(s)) {
        return -1;
    }

    for (i = 1; i < MAX_SOCKETS + 1; i++) {
        if (is_tcp_socket(i) &&
            (get_socket(i)->socket_values.local_address.sin6_port == name->sin6_port)) {
            return -1;
        }
    }

    memcpy(&get_socket(s)->socket_values.local_address, name, namelen);
    get_socket(s)->recv_pid = pid;
    get_socket(s)->socket_values.tcp_control.rto = TCP_INITIAL_ACK_TIMEOUT;
    return 0;
}
Esempio n. 8
0
int32_t destiny_socket_recv(int s, void *buf, uint32_t len, int flags)
{
    /* Variables */
    uint8_t read_bytes;
    msg_t m_recv, m_send;
    socket_internal_t *current_int_tcp_socket;

    /* Check if socket exists */
    if (!is_tcp_socket(s)) {
        printf("INFO: NO TCP SOCKET!\n");
        return -1;
    }

    current_int_tcp_socket = get_socket(s);

    /* Setting Thread PID */
    current_int_tcp_socket->recv_pid = thread_getpid();

    if (current_int_tcp_socket->tcp_input_buffer_end > 0) {
        return read_from_socket(current_int_tcp_socket, buf, len);
    }

    msg_receive(&m_recv);

    if ((exists_socket(s)) && (current_int_tcp_socket->tcp_input_buffer_end > 0)) {
        read_bytes = read_from_socket(current_int_tcp_socket, buf, len);
        net_msg_reply(&m_recv, &m_send, UNDEFINED);
        return read_bytes;
    }

    /* Received FIN */
    if (m_recv.type == CLOSE_CONN) {
        /* Sent FIN_ACK, wait for ACK */
        msg_receive(&m_recv);
        /* Received ACK, return with closed socket!*/
        return -1;
    }

    /* Received Last ACK (connection closed) or no data to read yet */
    return -1;
}
Esempio n. 9
0
int32_t destiny_socket_send(int s, const void *buf, uint32_t len, int flags)
{
    /* Variables */
    msg_t recv_msg;
    int32_t sent_bytes = 0, total_sent_bytes = 0;
    socket_internal_t *current_int_tcp_socket;
    socket_t *current_tcp_socket;
    uint8_t send_buffer[BUFFER_SIZE];
    memset(send_buffer, 0, 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 and is TCP socket */
    if (!is_tcp_socket(s)) {
        return -1;
    }

    current_int_tcp_socket = get_socket(s);
    current_tcp_socket = &current_int_tcp_socket->socket_values;

    /* Check for ESTABLISHED STATE */
    if (current_tcp_socket->tcp_control.state != ESTABLISHED) {
        return -1;
    }

    /* Add thread PID */
    current_int_tcp_socket->send_pid = thread_getpid();

    recv_msg.type = UNDEFINED;

    while (1) {
        current_tcp_socket->tcp_control.no_of_retries = 0;

#ifdef TCP_HC
        current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER;
        /* Remember TCP Context for possible TCP_RETRY */
        tcp_hc_context_t saved_tcp_context;
        memcpy(&saved_tcp_context, &current_tcp_socket->tcp_control.tcp_context,
               sizeof(tcp_hc_context_t) - 1);
#endif

        while (recv_msg.type != TCP_ACK) {
            /* Add packet data */
            if (current_tcp_socket->tcp_control.send_wnd >
                current_tcp_socket->tcp_control.mss) {
                /* Window size > Maximum Segment Size */
                if ((len - total_sent_bytes) > current_tcp_socket->tcp_control.mss) {
                    memcpy(&send_buffer[IPV6_HDR_LEN + TCP_HDR_LEN], buf,
                           current_tcp_socket->tcp_control.mss);
                    sent_bytes = current_tcp_socket->tcp_control.mss;
                    total_sent_bytes += sent_bytes;
                }
                else {
                    memcpy(&send_buffer[IPV6_HDR_LEN + TCP_HDR_LEN],
                           buf + total_sent_bytes, len - total_sent_bytes);
                    sent_bytes = len - total_sent_bytes;
                    total_sent_bytes = len;
                }
            }
            else {
                /* Window size <= Maximum Segment Size */
                if ((len - total_sent_bytes) > current_tcp_socket->tcp_control.send_wnd) {
                    memcpy(&send_buffer[IPV6_HDR_LEN + TCP_HDR_LEN], buf,
                           current_tcp_socket->tcp_control.send_wnd);
                    sent_bytes = current_tcp_socket->tcp_control.send_wnd;
                    total_sent_bytes += sent_bytes;
                }
                else {
                    memcpy(&send_buffer[IPV6_HDR_LEN + TCP_HDR_LEN],
                           buf + total_sent_bytes, len - total_sent_bytes);
                    sent_bytes = len - total_sent_bytes;
                    total_sent_bytes = len;
                }
            }

            current_tcp_socket->tcp_control.send_nxt += sent_bytes;
            current_tcp_socket->tcp_control.send_wnd -= sent_bytes;

            if (send_tcp(current_int_tcp_socket, current_tcp_packet,
                         temp_ipv6_header, 0, sent_bytes) != 1) {
                /* Error while sending tcp data */
                current_tcp_socket->tcp_control.send_nxt -= sent_bytes;
                current_tcp_socket->tcp_control.send_wnd += sent_bytes;
#ifdef TCP_HC
                memcpy(&current_tcp_socket->tcp_control.tcp_context,
                       &saved_tcp_context, sizeof(tcp_hc_context_t));
                current_tcp_socket->tcp_control.tcp_context.hc_type =
                    COMPRESSED_HEADER;
#endif
                printf("Error while sending, returning to application thread!\n");
                return -1;
            }

            /* Remember current time */
            current_tcp_socket->tcp_control.last_packet_time.microseconds =
                hwtimer_now();
            net_msg_receive(&recv_msg);

            switch (recv_msg.type) {
                case TCP_ACK: {
                    if (current_tcp_socket->tcp_control.no_of_retries == 0) {
                        calculate_rto(&current_tcp_socket->tcp_control,
                                      hwtimer_now());
                    }

                    tcp_hdr_t *tcp_header = ((tcp_hdr_t *)(recv_msg.content.ptr));

                    if ((current_tcp_socket->tcp_control.send_nxt ==
                         tcp_header->ack_nr) && (total_sent_bytes == len)) {
                        current_tcp_socket->tcp_control.send_una = tcp_header->ack_nr;
                        current_tcp_socket->tcp_control.send_nxt = tcp_header->ack_nr;
                        current_tcp_socket->tcp_control.send_wnd = tcp_header->window;
                        /* Got ACK for every sent byte */
#ifdef TCP_HC
                        current_tcp_socket->tcp_control.tcp_context.hc_type =
                            COMPRESSED_HEADER;
#endif
                        return sent_bytes;
                    }
                    else if ((current_tcp_socket->tcp_control.send_nxt ==
                              tcp_header->ack_nr) && (total_sent_bytes != len)) {
                        current_tcp_socket->tcp_control.send_una = tcp_header->ack_nr;
                        current_tcp_socket->tcp_control.send_nxt = tcp_header->ack_nr;
                        current_tcp_socket->tcp_control.send_wnd = tcp_header->window;
                        /* Got ACK for every sent byte */
#ifdef TCP_HC
                        current_tcp_socket->tcp_control.tcp_context.hc_type =
                            COMPRESSED_HEADER;
#endif
                        break;
                    }

                    /* else {
                     *     TODO: If window size > MSS, ACK was valid only for
                     *     a few segments, handle retransmit of missing
                     *     segments
                     *	break;
                     * } */
                    break;
                }

                case TCP_RETRY: {
                    current_tcp_socket->tcp_control.send_nxt -= sent_bytes;
                    current_tcp_socket->tcp_control.send_wnd += sent_bytes;
                    total_sent_bytes -= sent_bytes;
#ifdef TCP_HC
                    memcpy(&current_tcp_socket->tcp_control.tcp_context,
                           $&saved_tcp_context, sizeof(tcp_hc_context_t));
                    current_tcp_socket->tcp_control.tcp_context.hc_type =
                        MOSTLY_COMPRESSED_HEADER;
#endif
                    break;
                }

                case TCP_TIMEOUT: {
                    current_tcp_socket->tcp_control.send_nxt -= sent_bytes;
                    current_tcp_socket->tcp_control.send_wnd += sent_bytes;
#ifdef TCP_HC
                    memcpy(&current_tcp_socket->tcp_control.tcp_context,
                           &saved_tcp_context, sizeof(tcp_hc_context_t));
                    current_tcp_socket->tcp_control.tcp_context.hc_type =
                        COMPRESSED_HEADER;
#endif
                    return -1;
                    break;
                }
            }
        }
    }

    return sent_bytes;
}