diff --git a/app/kens/testtransfer.cpp b/app/kens/testtransfer.cpp index 3865373bd..ede714a7f 100644 --- a/app/kens/testtransfer.cpp +++ b/app/kens/testtransfer.cpp @@ -27,27 +27,6 @@ extern "C" { using namespace E; -/** - * @brief Server application for the transfer test - * - * This application is configured by the following environment variables. - * - * * `CONNECT_ADDR`, `CONNECT_PORT`: Parameters to configure a listening socket. - * * `CONNECT_TIME`: Arbitrary sleeping time before starting the handshake. If - * the handshake is completed but the established connection is not consumed - * by the server's `listen` system call, the backlog count will be decreased - * by one. - * * `START_TIME`: Arbitrary sleeping time before starting the data transfer. - * * `RANDOM_SEED`: This random seed is used to generate a pseudo-random byte - * stream. If a pair of server and client shares the same seed, the seed is - * used to generate and verify the data integrity. - * * `SENDER`: Determines who will send the data. Data transfer can be done in - * either client-to-server and server-to-client directions. - * * `BUFFER_SIZE`: Size of the buffer to be used in every `write` or `read` - * system call. - * * `LOOP_COUNT`: How many times the `write` system call will be invoked. - * * `EXPECT_SIZE`: Expected length of the received data. - */ class TestTransfer_Accept : public TCPApplication { public: TestTransfer_Accept(Host &host, @@ -182,26 +161,6 @@ class TestTransfer_Accept : public TCPApplication { } }; -/** - * @brief Client application for the transfer test - * - * This application is configured by the following environment variables. - * - * * `LISTEN_ADDR`, `LISTEN_PORT`, `BACKLOG`: Parameters to configure a - * listening socket. - * * `ACCEPT_TIME`: Arbitrary sleeping time before accepting sockets. If - * connections arrive during the sleep, they will consume the backlog count. - * * `START_TIME`: Arbitrary sleeping time before starting the data transfer. - * * `RANDOM_SEED`: This random seed is used to generate a pseudo-random byte - * stream. If a pair of server and client shares the same seed, the seed is - * used to generate and verify the data integrity. - * * `SENDER`: Determines who will send the data. Data transfer can be done in - * either client-to-server and server-to-client directions. - * * `BUFFER_SIZE`: Size of the buffer to be used in every `write` or `read` - * system call. - * * `LOOP_COUNT`: How many times the `write` system call will be invoked. - * * `EXPECT_SIZE`: Expected length of the received data. - */ class TestTransfer_Connect : public TCPApplication { public: TestTransfer_Connect(Host &host, @@ -318,14 +277,6 @@ class TestTransfer_Connect : public TCPApplication { } }; -/** - * Direction: Client -> Server - * - * In this case, the client will invoke `write` system call exactly N times, and - * the server will invoke `read` system call exactly N times. Thus, this test - * will gracefully accept cases when the `close` system call is not implemented - * correctly. - */ TEST_F(TestEnv_Any, TestTransfer_Connect_Send_Symmetric) { std::unordered_map accept_env; std::unordered_map connect_env; @@ -381,14 +332,6 @@ TEST_F(TestEnv_Any, TestTransfer_Connect_Send_Symmetric) { this->runTest(); } -/** - * Direction: Client -> Server - * - * In this case, the server does not know how many times the `write` system call - * will be invoked by the client. The server will indefinitly wait for the - * `read` system call unless the `EOF` is received. You should implement proper - * `close` semantics to pass this test. - */ TEST_F(TestEnv_Any, TestTransfer_Connect_Send_EOF) { std::unordered_map accept_env; std::unordered_map connect_env; @@ -444,12 +387,8 @@ TEST_F(TestEnv_Any, TestTransfer_Connect_Send_EOF) { this->runTest(); } -/** - * Data direction: Server -> Client. - * - * Same as `TestTransfer_Connect_Send_Symmetric` but the data direction is - * changed. - */ +//--------- + TEST_F(TestEnv_Any, TestTransfer_Connect_Recv_Symmetric) { std::unordered_map accept_env; std::unordered_map connect_env; @@ -505,11 +444,6 @@ TEST_F(TestEnv_Any, TestTransfer_Connect_Recv_Symmetric) { this->runTest(); } -/** - * Data direction: Server -> Client. - * - * Same as `TestTransfer_Connect_Send_EOF` but the data direction is changed. - */ TEST_F(TestEnv_Any, TestTransfer_Connect_Recv_EOF) { std::unordered_map accept_env; std::unordered_map connect_env; @@ -565,13 +499,6 @@ TEST_F(TestEnv_Any, TestTransfer_Connect_Recv_EOF) { this->runTest(); } -/** - * Data direction: Server -> Client. - * - * In this case, the server uses a very small buffer (128B) while the client - * sends large packets (>=512B). Assuming that a packet has 512B data, it will - * be used to fill the read buffer of 4 consequent `read` system calls. - */ TEST_F(TestEnv_Any, TestTransfer_Connect_Recv_SmallBuffer1) { std::unordered_map accept_env; std::unordered_map connect_env; @@ -627,14 +554,6 @@ TEST_F(TestEnv_Any, TestTransfer_Connect_Recv_SmallBuffer1) { this->runTest(); } -/** - * Data direction: Server -> Client. - * - * In this case, the server uses an extreamly small buffer (67B). This is only 3 - * bytes larger than the minimum size of the ethernet frame. Unlike the - * previous example, the small buffer size no longer divides the size of the - * large client buffer without remainders. - */ TEST_F(TestEnv_Any, TestTransfer_Connect_Recv_SmallBuffer2) { std::unordered_map accept_env; std::unordered_map connect_env; @@ -690,9 +609,8 @@ TEST_F(TestEnv_Any, TestTransfer_Connect_Recv_SmallBuffer2) { this->runTest(); } -/** - * Exactly as same as the `TestTransfer_Connect_Recv_Symmetric` - */ +//====================================== + TEST_F(TestEnv_Any, TestTransfer_Accept_Send_Symmetric) { std::unordered_map accept_env; std::unordered_map connect_env; @@ -748,10 +666,6 @@ TEST_F(TestEnv_Any, TestTransfer_Accept_Send_Symmetric) { this->runTest(); } -/** - * In `TestTransfer_Connect_Recv_EOF` test, the client sends the EOF signal. In - * this test, the server sends the EOF signal. - */ TEST_F(TestEnv_Any, TestTransfer_Accept_Send_EOF) { std::unordered_map accept_env; std::unordered_map connect_env; @@ -807,9 +721,8 @@ TEST_F(TestEnv_Any, TestTransfer_Accept_Send_EOF) { this->runTest(); } -/** - * Same as the `TestTransfer_Connect_Send_Symmetric` test. - */ +//--------- + TEST_F(TestEnv_Any, TestTransfer_Accept_Recv_Symmetric) { std::unordered_map accept_env; std::unordered_map connect_env; @@ -865,10 +778,6 @@ TEST_F(TestEnv_Any, TestTransfer_Accept_Recv_Symmetric) { this->runTest(); } -/** - * In `TestTransfer_Connect_Send_EOF` test, the client sends the EOF signal. In - * this test, the server sends the EOF signal. - */ TEST_F(TestEnv_Any, TestTransfer_Accept_Recv_EOF) { std::unordered_map accept_env; std::unordered_map connect_env; @@ -924,10 +833,6 @@ TEST_F(TestEnv_Any, TestTransfer_Accept_Recv_EOF) { this->runTest(); } -/** - * Same as the `TestTransfer_Connect_Recv_SmallBuffer1` test except for the data - * transfer direction. - */ TEST_F(TestEnv_Any, TestTransfer_Accept_Recv_SmallBuffer1) { std::unordered_map accept_env; std::unordered_map connect_env; @@ -983,10 +888,6 @@ TEST_F(TestEnv_Any, TestTransfer_Accept_Recv_SmallBuffer1) { this->runTest(); } -/** - * Same as the `TestTransfer_Accept_Recv_SmallBuffer2` test except for the data - * transfer direction. - */ TEST_F(TestEnv_Any, TestTransfer_Accept_Recv_SmallBuffer2) { std::unordered_map accept_env; std::unordered_map connect_env; diff --git a/include/E/Networking/E_Host.hpp b/include/E/Networking/E_Host.hpp index d0d6bf987..98f304b54 100644 --- a/include/E/Networking/E_Host.hpp +++ b/include/E/Networking/E_Host.hpp @@ -107,6 +107,13 @@ class HostModule { */ Size getWireSpeed(int port_num); + /** + * @brief Get the number of ports + * + * @return the number of ports + */ + size_t getPortCount(); + /** * @brief Prints log with specified log level and format. * NetworkLog::print_log prints logs specified in log level parameter. @@ -340,9 +347,7 @@ class Host : public NetworkModule, public NetworkLog, public RoutingInfo { class ProcessInfo { public: std::shared_ptr application; - std::unordered_set fdSet; - std::unordered_map fdToDomain; - int fdStart; + std::map fdToDomain; }; int pidStart; diff --git a/src/Networking/E_Host.cpp b/src/Networking/E_Host.cpp index 1a2cec6f4..e4a3537e0 100644 --- a/src/Networking/E_Host.cpp +++ b/src/Networking/E_Host.cpp @@ -247,6 +247,8 @@ Size HostModule::getWireSpeed(int port_num) { return host.getWireSpeed(port_num); } +size_t HostModule::getPortCount() { return host.getPortCount(); } + void HostModule::print_log(uint64_t level, const char *format, ...) { va_list arglist; va_start(arglist, format); @@ -337,24 +339,26 @@ void Host::returnSystemCall(UUID syscallUUID, int val) { int Host::createFileDescriptor(int domain, int protocol, int processID) { assert(processInfoMap.find(processID) != processInfoMap.end()); ProcessInfo &procInfo = processInfoMap.find(processID)->second; - int start = procInfo.fdStart; - int current = start; + int current = 3; // assert(procInfo.fdSet.find(processID) != procInfo.fdSet.end()); - do { - if (procInfo.fdSet.find(current) == procInfo.fdSet.end()) { - procInfo.fdSet.insert(current); - procInfo.fdStart = (current + 1) % MAX_FD; - procInfo.fdToDomain.insert( - std::pair(current, Namespace(domain, protocol))); - // found proper fd number - return current; - } - current = (current + 1) % MAX_FD; - } while (start != current); + auto it = procInfo.fdToDomain.begin(); - print_log(NetworkLog::SYSCALL_ERROR, "Out of FD for process %d.", processID); - return -1; + while (it != procInfo.fdToDomain.end() && it->first == current) { + ++current; + ++it; + } + + if (current >= MAX_FD) { + + print_log(NetworkLog::SYSCALL_ERROR, "Out of FD for process %d.", + processID); + return -1; + } + procInfo.fdToDomain.insert( + std::pair(current, Namespace(domain, protocol))); + + return current; } void Host::removeFileDescriptor(int processID, int fd) { @@ -362,7 +366,6 @@ void Host::removeFileDescriptor(int processID, int fd) { if (processInfoMap.find(processID) != processInfoMap.end()) { ProcessInfo &procInfo = processInfoMap.find(processID)->second; - procInfo.fdSet.erase(fd); procInfo.fdToDomain.erase(fd); } } @@ -373,7 +376,6 @@ int Host::registerProcess(std::shared_ptr app) { do { if (processInfoMap.find(current) == processInfoMap.end()) { ProcessInfo procInfo; - procInfo.fdStart = 0; app->pid = current; procInfo.application = std::move(app); processInfoMap.insert(