-
Notifications
You must be signed in to change notification settings - Fork 0
[FW-79]- Creation of ethernet Mock #438
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
g0nz4I0
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good, I dont understand the purpose of the timeout, and if you can install callbacks maybe we can do that? instead of the thread. IPV4 interface I like the small changes
Remove all the #ifdef guards
I like the std::lock_guard
Inc/HALALMock/Services/Communication/Ethernet/TCP/ServerSocket.hpp
Outdated
Show resolved
Hide resolved
Inc/HALALMock/Services/Communication/Ethernet/TCP/ServerSocket.hpp
Outdated
Show resolved
Hide resolved
jmaralo
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are some corner cases that I pointed out that I got after working two years with sockets from Go which might get you if you don't know them.
I also thing there is a lot of refactoring that can be done to make the code much cleaner and easy to follow. Is easy for the code to get messy with all the syscalls and error handling ifs.
| queue<vector<uint8_t>> tx_packet_buffer; | ||
| queue<vector<uint8_t>> rx_packet_buffer; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do think it will be better (and less obscure what you are sending) by storing a pointer to a packet
| fd_set write_fds; | ||
| FD_ZERO(&write_fds); | ||
| FD_SET(socket_fd, &write_fds); | ||
| //timeout | ||
| struct timeval timeout; | ||
| timeout.tv_sec = 5; | ||
| timeout.tv_usec = 0; | ||
| //use select to check if fthe socket has established connection | ||
| int result = select(socket_fd + 1, NULL, &write_fds, NULL, &timeout); | ||
| if (result > 0 && FD_ISSET(socket_fd, &write_fds)) { | ||
| //If it's connected we do as connected_callback | ||
| if(connecting_sockets.contains(remote_node)){ | ||
| connecting_sockets.erase(remote_node); | ||
| state = CONNECTED; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't know if this will even work, what happens if the client connects after 5s? will the connection_callback ever be called?
There is a cleaner way, you can use poll (more modern than select) inside a thread. Basically you will create a thread like this:
// check beforehand the connection worked
std::thread wait_for_connection([&](){
// create here the pollfs struct in a variable called socket_event
int result = poll(socket_event, 1, -1); // -1 means to never timeout
// check the result here
connection_callback();
});
// don't join the thread, store it somewhere or even deatatch itfill in the blanks and it should work well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
| while (!tx_packet_buffer.empty()) { | ||
| vector<uint8_t> packet = tx_packet_buffer.front(); | ||
| ssize_t sent_bytes = ::send(socket_fd, packet.data(), packet.size(), 0); | ||
| HeapPacket packet = tx_packet_buffer.front(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pointer or reference type, Packet* will do
|
|
| while (!tx_packet_buffer.empty()) { | ||
| HeapPacket packet = tx_packet_buffer.front(); | ||
| ssize_t sent_bytes = ::send(socket_fd, packet.build(), packet.get_size(), 0); | ||
| HeapPacket *packet = tx_packet_buffer.front(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Packet*
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you explain this, at the end packet is a virtual class to store data shouldn't I use one class derivated from packet
jmaralo
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gave it a quick read and didn't find anything weird, keep going at it so we can start seeing where compilation fails. But I'll point out just two things
| //to reuse local address: | ||
| int opt = 1; | ||
| if (setsockopt(server_socket_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { | ||
| std::cerr << "Error setting SO_REUSEADDR\n"; | ||
| close(server_socket_fd); | ||
| return; | ||
| } | ||
| //disable naggle algorithm | ||
| int flag = 1; | ||
| if (setsockopt(server_socket_fd,IPPROTO_TCP,TCP_NODELAY,(char *) &flag, sizeof(int)) < 0){ | ||
| std::cout<<"It has been an error disabling Nagle's algorithm\n"; | ||
| close(server_socket_fd); | ||
| return; | ||
| } | ||
| //habilitate keepalives | ||
| int optval = 1; | ||
| if (setsockopt(server_socket_fd, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) < 0) { | ||
| std::cout << "ERROR configuring KEEPALIVES\n"; | ||
| close(server_socket_fd); | ||
| return; | ||
| } | ||
| // Configurar TCP_KEEPIDLE it sets what time to wait to start sending keepalives | ||
| float tcp_keepidle_time = static_cast<float>(keepalive_config.inactivity_time_until_keepalive_ms)/1000.0; | ||
| if (setsockopt(server_socket_fd, IPPROTO_TCP, TCP_KEEPIDLE, &tcp_keepidle_time, sizeof(tcp_keepidle_time)) < 0) { | ||
| std::cout << "Error configuring TCP_KEEPIDLE\n"; | ||
| close(server_socket_fd); | ||
| return; | ||
| } | ||
| //interval between keepalives | ||
| float keep_interval_time = static_cast<float>(keepalive_config.space_between_tries_ms)/1000.0; | ||
| if (setsockopt(server_socket_fd, IPPROTO_TCP, TCP_KEEPINTVL, &keep_interval_time, sizeof(keep_interval_time)) < 0) { | ||
| std::cout << "Error configuring TCP_KEEPINTVL\n"; | ||
| close(server_socket_fd); | ||
| return; | ||
| } | ||
| // Configure TCP_KEEPCNT (number keepalives are send before considering the connection down) | ||
| float keep_cnt = static_cast<float>(keepalive_config.tries_until_disconnection)/1000.0; | ||
| if (setsockopt(server_socket_fd, IPPROTO_TCP, TCP_KEEPCNT, &keep_cnt, sizeof(keep_cnt)) < 0) { | ||
| std::cout << "Error to configure TCP_KEEPCNT\n"; | ||
| close(server_socket_fd); | ||
| return ; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would still separate into more functions, but just a nitpick, also, return a bool that is true if the configuration was successful or false in any other case
…changes in serverSocket to only have one connection
|
I don't know how to wite a description of the pr once I changed it from draft to open, so I will leave this message explaining the pr. During this pr I've tried to convert the code from the lwip to sockets in linux. But always trying to replicate the behave of the halal. we will have to create test to assure the well behave of the pr. The changes have been done in these files: Ethernet, Pin,IPV4, Socket, ServerSocket and DatagramSocket |
jmaralo
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm approving the PR because it has been open for too long. There are a few things that won't work with ServerSocket from the way it worked with LWIP and the way it works in linux. I think we should merge this PR and fix those things later on with new jira tickets
| if(sendto(udp_socket,packet_buffer,size,0,(struct sockaddr *)&remote_socket_addr, sizeof(remote_socket_addr)) < 0){ | ||
| close(udp_socket); | ||
| return false; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sendto might not send all the data in one go, you should do a while loop until all the data is sent
| ServerSocket::ServerSocket(IPV4 local_ip, uint32_t local_port) : local_ip(local_ip),local_port(local_port){ | ||
| if(not Ethernet::is_running) { | ||
| ErrorHandler("Cannot declare UDP socket before Ethernet::start()"); | ||
| cout<<"Cannot declare UDP socket before Ethernet::start()\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ErrorHandler
| // Clean all descriptors | ||
| if (client_fd != -1) { | ||
| ::close(client_fd); | ||
| client_fd = -1; | ||
| } | ||
| if (server_socket_fd != -1) { | ||
| ::close(server_socket_fd); | ||
| server_socket_fd = -1; | ||
| } | ||
| //clean the transmisions buffers | ||
| while (!tx_packet_buffer.empty()) { | ||
| tx_packet_buffer.pop(); | ||
| } | ||
| while (!rx_packet_buffer.empty()) { | ||
| rx_packet_buffer.pop(); | ||
| } | ||
| //eliminate the threads | ||
| if(state == LISTENING){ | ||
| ~listening_thread(); | ||
| }else if(state == ACCEPTED){ | ||
| ~receive_thread(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont know if closing both in the close method and in the destructor will give any problems, because usually doing a double close returns an error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also see that in the HALAL the implementation is different for close and for the destructor
325618a to
d646c28
Compare
oganigl
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this pr it has to been check by testing it.
No description provided.