update,
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
*Copyright (C) 2023 Carnegie Mellon University and
|
||||
*Hong Kong University of Science and Technology
|
||||
|
||||
*This repository is adopted from the TCP in the
|
||||
*Wild course project from the Computer Networks
|
||||
*course taught at Carnegie Mellon University, and
|
||||
*is used for the Computer Networks (ELEC 3120)
|
||||
*course taught at Hong Kong University of Science
|
||||
*and Technology.
|
||||
|
||||
*No part of the project may be copied and/or
|
||||
*distributed without the express permission of
|
||||
*the course staff. Everyone is prohibited from
|
||||
*releasing their forks in any public places.
|
||||
*
|
||||
*
|
||||
* This file defines the function signatures for the CMU-TCP backend that should
|
||||
* be exposed. The backend runs in a different thread and handles all the socket
|
||||
* operations separately from the application.
|
||||
*/
|
||||
|
||||
#ifndef PROJECT_1_ELEC3120_INC_BACKEND_H_
|
||||
#define PROJECT_1_ELEC3120_INC_BACKEND_H_
|
||||
|
||||
/**
|
||||
* Launches the CMU-TCP backend.
|
||||
*
|
||||
* @param in the socket to be used for backend processing.
|
||||
*/
|
||||
void* begin_backend(void* in);
|
||||
|
||||
#endif // PROJECT_1_ELEC3120_INC_BACKEND_H_
|
@@ -0,0 +1,182 @@
|
||||
/**
|
||||
*Copyright (C) 2023 Carnegie Mellon University and
|
||||
*Hong Kong University of Science and Technology
|
||||
|
||||
*This repository is adopted from the TCP in the
|
||||
*Wild course project from the Computer Networks
|
||||
*course taught at Carnegie Mellon University, and
|
||||
*is used for the Computer Networks (ELEC 3120)
|
||||
*course taught at Hong Kong University of Science
|
||||
*and Technology.
|
||||
|
||||
*No part of the project may be copied and/or
|
||||
*distributed without the express permission of
|
||||
*the course staff. Everyone is prohibited from
|
||||
*releasing their forks in any public places.
|
||||
*
|
||||
* Defines a CMU-TCP packet and define helper functions to create and manipulate
|
||||
* packets.
|
||||
*
|
||||
* Do NOT modify this file.
|
||||
*/
|
||||
|
||||
#ifndef PROJECT_1_ELEC3120_INC_CMU_PACKET_H_
|
||||
#define PROJECT_1_ELEC3120_INC_CMU_PACKET_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
uint32_t identifier; // Identifier for the CMU-TCP protocol.
|
||||
uint16_t source_port; // Source port.
|
||||
uint16_t destination_port; // Destination port.
|
||||
uint32_t seq_num; // Sequence number.
|
||||
uint32_t ack_num; // Acknowledgement number.
|
||||
uint16_t hlen; // Header length.
|
||||
uint16_t plen; // Packet length.
|
||||
uint8_t flags; // Flags.
|
||||
uint16_t advertised_window; // Advertised window.
|
||||
uint16_t extension_length; // Extension length.
|
||||
uint8_t extension_data[]; // Extension data.
|
||||
} __attribute__((__packed__)) cmu_tcp_header_t;
|
||||
|
||||
#define SYN_FLAG_MASK 0x8
|
||||
#define ACK_FLAG_MASK 0x4
|
||||
#define FIN_FLAG_MASK 0x2
|
||||
#define IDENTIFIER 15441
|
||||
|
||||
// Maximum Segment Size. Make sure to update this if your CCA requires extension
|
||||
// data for all packets, as this reduces the payload and thus the MSS.
|
||||
#define MSS (MAX_LEN - sizeof(cmu_tcp_header_t))
|
||||
|
||||
/* Helper functions to get/set fields in the header */
|
||||
|
||||
uint16_t get_src(cmu_tcp_header_t* header);
|
||||
uint16_t get_dst(cmu_tcp_header_t* header);
|
||||
uint32_t get_seq(cmu_tcp_header_t* header);
|
||||
uint32_t get_ack(cmu_tcp_header_t* header);
|
||||
uint16_t get_hlen(cmu_tcp_header_t* header);
|
||||
uint16_t get_plen(cmu_tcp_header_t* header);
|
||||
uint8_t get_flags(cmu_tcp_header_t* header);
|
||||
uint16_t get_advertised_window(cmu_tcp_header_t* header);
|
||||
uint16_t get_extension_length(cmu_tcp_header_t* header);
|
||||
uint8_t* get_extension_data(cmu_tcp_header_t* header);
|
||||
|
||||
void set_src(cmu_tcp_header_t* header, uint16_t src);
|
||||
void set_dst(cmu_tcp_header_t* header, uint16_t dst);
|
||||
void set_seq(cmu_tcp_header_t* header, uint32_t seq);
|
||||
void set_ack(cmu_tcp_header_t* header, uint32_t ack);
|
||||
void set_hlen(cmu_tcp_header_t* header, uint16_t hlen);
|
||||
void set_plen(cmu_tcp_header_t* header, uint16_t plen);
|
||||
void set_flags(cmu_tcp_header_t* header, uint8_t flags);
|
||||
void set_advertised_window(cmu_tcp_header_t* header,
|
||||
uint16_t advertised_window);
|
||||
void set_extension_length(cmu_tcp_header_t* header, uint16_t extension_length);
|
||||
void set_extension_data(cmu_tcp_header_t* header, uint8_t* extension_data);
|
||||
|
||||
/**
|
||||
* Sets all the header fields.
|
||||
*
|
||||
* Review TCP headers for more information about what each field means.
|
||||
*
|
||||
* @param header The header to set the fields.
|
||||
* @param src Source port.
|
||||
* @param dst Destination port.
|
||||
* @param seq Sequence number.
|
||||
* @param ack Acknowledgement number.
|
||||
* @param hlen Header length.
|
||||
* @param plen Packet length.
|
||||
* @param flags Packet flags.
|
||||
* @param advertised_window Advertised window.
|
||||
* @param extension_length Header extension length.
|
||||
* @param extension_data Header extension data.
|
||||
*/
|
||||
void set_header(cmu_tcp_header_t* header, uint16_t src, uint16_t dst,
|
||||
uint32_t seq, uint32_t ack, uint16_t hlen, uint16_t plen,
|
||||
uint8_t flags, uint16_t adv_window, uint16_t ext,
|
||||
uint8_t* ext_data);
|
||||
|
||||
/**
|
||||
* Gets a pointer to the packet payload.
|
||||
*
|
||||
* @param pkt The packet to get the payload.
|
||||
*
|
||||
* @return A pointer to the payload.
|
||||
*/
|
||||
uint8_t* get_payload(uint8_t* pkt);
|
||||
|
||||
/**
|
||||
* Gets the length of the packet payload.
|
||||
*
|
||||
* @param pkt The packet to get the payload length.
|
||||
*
|
||||
* @return The length of the payload.
|
||||
*/
|
||||
uint16_t get_payload_len(uint8_t* pkt);
|
||||
|
||||
/**
|
||||
* Sets the packet payload.
|
||||
*
|
||||
* @param pkt The packet to set the payload.
|
||||
* @param payload A pointer to the payload to be set.
|
||||
* @param payload_len The length of the payload.
|
||||
*/
|
||||
void set_payload(uint8_t* pkt, uint8_t* payload, uint16_t payload_len);
|
||||
|
||||
/**
|
||||
* Allocates and initializes a packet.
|
||||
*
|
||||
* @param src The source port.
|
||||
* @param dst The destination port.
|
||||
* @param seq The sequence number.
|
||||
* @param ack The acknowledgement number.
|
||||
* @param hlen The header length.
|
||||
* @param plen The packet length.
|
||||
* @param flags The flags.
|
||||
* @param adv_window The advertised window.
|
||||
* @param ext_len The header extension length.
|
||||
* @param ext_data The header extension data.
|
||||
* @param payload The payload.
|
||||
* @param payload_len The length of the payload.
|
||||
*
|
||||
* @return A pointer to the newly allocated packet. User must `free` after use.
|
||||
*/
|
||||
uint8_t* create_packet(uint16_t src, uint16_t dst, uint32_t seq, uint32_t ack,
|
||||
uint16_t hlen, uint16_t plen, uint8_t flags,
|
||||
uint16_t adv_window, uint16_t ext_len, uint8_t* ext_data,
|
||||
uint8_t* payload, uint16_t payload_len);
|
||||
|
||||
/**
|
||||
* Checks if a given sequence number comes before another sequence number.
|
||||
*
|
||||
* @param seq1 the first sequence number.
|
||||
* @param seq2 the second sequence number.
|
||||
* @return 1 if seq1 comes before seq2, 0 otherwise.
|
||||
*/
|
||||
static inline int before(uint32_t seq1, uint32_t seq2) {
|
||||
return (int32_t)(seq1 - seq2) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a given sequence number comes after another sequence number.
|
||||
*
|
||||
* @param seq1 the first sequence number.
|
||||
* @param seq2 the second sequence number.
|
||||
* @return 1 if seq1 comes after seq2, 0 otherwise.
|
||||
*/
|
||||
static inline int after(uint32_t seq1, uint32_t seq2) {
|
||||
return before(seq2, seq1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a given sequence number is between two others.
|
||||
*
|
||||
* @param seq the sequence number.
|
||||
* @param low the lower bound.
|
||||
* @param high the upper bound.
|
||||
* @return 1 if low <= seq <= high, 0 otherwise.
|
||||
*/
|
||||
static inline int between(uint32_t seq, uint32_t low, uint32_t high) {
|
||||
return high - low >= seq - low;
|
||||
}
|
||||
|
||||
#endif // PROJECT_1_ELEC3120_INC_CMU_PACKET_H_
|
@@ -0,0 +1,145 @@
|
||||
/**
|
||||
*Copyright (C) 2023 Carnegie Mellon University and
|
||||
*Hong Kong University of Science and Technology
|
||||
|
||||
*This repository is adopted from the TCP in the
|
||||
*Wild course project from the Computer Networks
|
||||
*course taught at Carnegie Mellon University, and
|
||||
*is used for the Computer Networks (ELEC 3120)
|
||||
*course taught at Hong Kong University of Science
|
||||
*and Technology.
|
||||
|
||||
*No part of the project may be copied and/or
|
||||
*distributed without the express permission of
|
||||
*the course staff. Everyone is prohibited from
|
||||
*releasing their forks in any public places.
|
||||
*
|
||||
*
|
||||
* This file defines the API for the CMU TCP implementation.
|
||||
*/
|
||||
|
||||
#ifndef PROJECT_1_ELEC3120_INC_CMU_TCP_H_
|
||||
#define PROJECT_1_ELEC3120_INC_CMU_TCP_H_
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "cmu_packet.h"
|
||||
#include "grading.h"
|
||||
|
||||
#define EXIT_SUCCESS 0
|
||||
#define EXIT_ERROR -1
|
||||
#define EXIT_FAILURE 1
|
||||
|
||||
typedef struct {
|
||||
uint32_t next_seq_expected;
|
||||
uint32_t last_ack_received;
|
||||
pthread_mutex_t ack_lock;
|
||||
} window_t;
|
||||
|
||||
/**
|
||||
* CMU-TCP socket types. (DO NOT CHANGE.)
|
||||
*/
|
||||
typedef enum {
|
||||
TCP_INITIATOR = 0,
|
||||
TCP_LISTENER = 1,
|
||||
} cmu_socket_type_t;
|
||||
|
||||
/**
|
||||
* This structure holds the state of a socket. You may modify this structure as
|
||||
* you see fit to include any additional state you need for your implementation.
|
||||
*/
|
||||
typedef struct {
|
||||
int socket;
|
||||
pthread_t thread_id;
|
||||
uint16_t my_port;
|
||||
struct sockaddr_in conn;
|
||||
uint8_t* received_buf;
|
||||
int received_len;
|
||||
pthread_mutex_t recv_lock;
|
||||
pthread_cond_t wait_cond;
|
||||
uint8_t* sending_buf;
|
||||
int sending_len;
|
||||
cmu_socket_type_t type;
|
||||
pthread_mutex_t send_lock;
|
||||
int dying;
|
||||
pthread_mutex_t death_lock;
|
||||
window_t window;
|
||||
} cmu_socket_t;
|
||||
|
||||
/*
|
||||
* DO NOT CHANGE THE DECLARATIONS BELOW
|
||||
*/
|
||||
|
||||
/**
|
||||
* Read mode flags supported by a CMU-TCP socket.
|
||||
*/
|
||||
typedef enum {
|
||||
NO_FLAG = 0, // Default behavior: block indefinitely until data is available.
|
||||
NO_WAIT, // Return immediately if no data is available.
|
||||
TIMEOUT, // Block until data is available or the timeout is reached.
|
||||
} cmu_read_mode_t;
|
||||
|
||||
/**
|
||||
* Constructs a CMU-TCP socket.
|
||||
*
|
||||
* An Initiator socket is used to connect to a Listener socket.
|
||||
*
|
||||
* @param sock The structure with the socket state. It will be initialized by
|
||||
* this function.
|
||||
* @param socket_type Indicates the type of socket: Listener or Initiator.
|
||||
* @param port Port to either connect to, or bind to. (Based on socket_type.)
|
||||
* @param server_ip IP address of the server to connect to. (Only used if the
|
||||
* socket is an initiator.)
|
||||
*
|
||||
* @return 0 on success, -1 on error.
|
||||
*/
|
||||
int cmu_socket(cmu_socket_t* sock, const cmu_socket_type_t socket_type,
|
||||
const int port, const char* server_ip);
|
||||
|
||||
/**
|
||||
* Closes a CMU-TCP socket.
|
||||
*
|
||||
* @param sock The socket to close.
|
||||
*
|
||||
* @return 0 on success, -1 on error.
|
||||
*/
|
||||
int cmu_close(cmu_socket_t* sock);
|
||||
|
||||
/**
|
||||
* Reads data from a CMU-TCP socket.
|
||||
*
|
||||
* If there is data available in the socket buffer, it is placed in the
|
||||
* destination buffer.
|
||||
*
|
||||
* @param sock The socket to read from.
|
||||
* @param buf The buffer to read into.
|
||||
* @param length The maximum number of bytes to read.
|
||||
* @param flags Flags that determine how the socket should wait for data. Check
|
||||
* `cmu_read_mode_t` for more information. `TIMEOUT` is not
|
||||
* implemented for CMU-TCP.
|
||||
*
|
||||
* @return The number of bytes read on success, -1 on error.
|
||||
*/
|
||||
int cmu_read(cmu_socket_t* sock, void* buf, const int length,
|
||||
cmu_read_mode_t flags);
|
||||
|
||||
/**
|
||||
* Writes data to a CMU-TCP socket.
|
||||
*
|
||||
* @param sock The socket to write to.
|
||||
* @param buf The data to write.
|
||||
* @param length The number of bytes to write.
|
||||
*
|
||||
* @return 0 on success, -1 on error.
|
||||
*/
|
||||
int cmu_write(cmu_socket_t* sock, const void* buf, int length);
|
||||
|
||||
/*
|
||||
* You can declare more functions after this point if you need to.
|
||||
*/
|
||||
|
||||
#endif // PROJECT_1_ELEC3120_INC_CMU_TCP_H_
|
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
*Copyright (C) 2023 Carnegie Mellon University and
|
||||
*Hong Kong University of Science and Technology
|
||||
|
||||
*This repository is adopted from the TCP in the
|
||||
*Wild course project from the Computer Networks
|
||||
*course taught at Carnegie Mellon University, and
|
||||
*is used for the Computer Networks (ELEC 3120)
|
||||
*course taught at Hong Kong University of Science
|
||||
*and Technology.
|
||||
|
||||
*No part of the project may be copied and/or
|
||||
*distributed without the express permission of
|
||||
*the course staff. Everyone is prohibited from
|
||||
*releasing their forks in any public places.
|
||||
*
|
||||
*
|
||||
* This files defines constants used for grading. Do NOT modify this file as
|
||||
* any changes will be overwritten by the autograder.
|
||||
*/
|
||||
|
||||
#ifndef PROJECT_1_ELEC3120_INC_GRADING_H_
|
||||
#define PROJECT_1_ELEC3120_INC_GRADING_H_
|
||||
|
||||
/*
|
||||
* DO NOT CHANGE THIS FILE
|
||||
* This contains the variables for your TCP implementation
|
||||
* and we will replace this file during the autolab testing with new variables.
|
||||
*/
|
||||
|
||||
// packet lengths
|
||||
#define MAX_LEN 1400
|
||||
|
||||
// window variables
|
||||
#define WINDOW_INITIAL_WINDOW_SIZE (MSS * 16)
|
||||
#define WINDOW_INITIAL_SSTHRESH (MSS * 64)
|
||||
#define WINDOW_INITIAL_RTT 3000 // ms
|
||||
#define WINDOW_INITIAL_ADVERTISED MSS
|
||||
|
||||
// Max TCP Buffer
|
||||
#define MAX_NETWORK_BUFFER 65535 // (2^16 - 1) bytes
|
||||
|
||||
#endif // PROJECT_1_ELEC3120_INC_GRADING_H_
|
Reference in New Issue
Block a user