Skip to content

Commit

Permalink
Extract the UDP testing code to a separate file.
Browse files Browse the repository at this point in the history
  • Loading branch information
trekawek authored and tschak909 committed May 27, 2024
1 parent 40856de commit 083956f
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 81 deletions.
1 change: 1 addition & 0 deletions fujinet_pc.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ set(SOURCES src/main.cpp
lib/ftp/fnFTP.h lib/ftp/fnFTP.cpp
lib/TNFSlib/tnfslibMountInfo.h lib/TNFSlib/tnfslibMountInfo.cpp
lib/TNFSlib/tnfslib.h lib/TNFSlib/tnfslib.cpp
lib/TNFSlib/tnfslib_udp.h lib/TNFSlib/tnfslib_udp_testing.cpp
lib/telnet/libtelnet.h lib/telnet/libtelnet.c
lib/fnjson/fnjson.h lib/fnjson/fnjson.cpp
components_pc/mongoose/mongoose.h components_pc/mongoose/mongoose.c
Expand Down
160 changes: 79 additions & 81 deletions lib/TNFSlib/tnfslib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "bus.h"
#include "fnUDP.h"
#include "fnTcpClient.h"
#include "tnfslib_udp.h"

#include "utils.h"

Expand Down Expand Up @@ -46,8 +47,9 @@ typedef enum

bool _tnfs_transaction(tnfsMountInfo *m_info, tnfsPacket &pkt, uint16_t datalen);
bool _tnfs_send(fnUDP *udp, tnfsMountInfo *m_info, tnfsPacket &pkt, uint16_t payload_size);
bool _tnfs_udp_send(fnUDP *udp, tnfsMountInfo *m_info, tnfsPacket &pkt, uint16_t payload_size);
int _tnfs_recv(fnUDP *udp, tnfsMountInfo *m_info, tnfsPacket &pkt);
bool _tnfs_tcp_send(tnfsMountInfo *m_info, tnfsPacket &pkt, uint16_t payload_size);
int _tnfs_tcp_recv(tnfsMountInfo *m_info, tnfsPacket &pkt);
_tnfs_send_recv_result _tnfs_send_recv(fnUDP &udp, tnfsMountInfo *m_info, tnfsPacket &req_pkt, uint16_t payload_size, tnfsPacket &res_pkt);
_tnfs_recv_result _tnfs_recv_and_validate(fnUDP &udp, tnfsMountInfo *m_info, tnfsPacket &req_pkt, uint16_t payload_size, tnfsPacket &res_pkt);
uint8_t _tnfs_session_recovery(tnfsMountInfo *m_info, uint8_t command);
Expand Down Expand Up @@ -1254,64 +1256,69 @@ const char *tnfs_getcwd(tnfsMountInfo *m_info)
*/
bool _tnfs_send(fnUDP *udp, tnfsMountInfo *m_info, tnfsPacket &pkt, uint16_t payload_size)
{
if (m_info->protocol == TNFS_PROTOCOL_UNKNOWN || m_info->protocol == TNFS_PROTOCOL_TCP)
if (m_info->protocol == TNFS_PROTOCOL_UNKNOWN)
{
fnTcpClient *tcp = &m_info->tcp_client;
if (!tcp->connected())
bool success = _tnfs_tcp_send(m_info, pkt, payload_size);
if (!success)
{
bool success = false;
if (m_info->host_ip != IPADDR_NONE)
success = tcp->connect(m_info->host_ip, m_info->port, TNFS_TIMEOUT);
else
success = tcp->connect(m_info->hostname, m_info->port, TNFS_TIMEOUT);
if (!success && m_info->protocol == TNFS_PROTOCOL_UNKNOWN)
{
Debug_println("Can't connect to the TCP server; falling back to UDP.");
m_info->protocol = TNFS_PROTOCOL_UDP;
return _tnfs_send(udp, m_info, pkt, payload_size);
}
if (!success)
{
Debug_println("Can't connect to the TCP server");
return false;
}
Debug_println("Can't connect to the TCP server; falling back to UDP.");
m_info->protocol = TNFS_PROTOCOL_UDP;
return _tnfs_udp_send(udp, m_info, pkt, payload_size);
}
int l = tcp->write(pkt.rawData, payload_size + TNFS_HEADER_SIZE);
return l == payload_size + TNFS_HEADER_SIZE;
return success;
}
else if (m_info->protocol == TNFS_PROTOCOL_TCP)
{
return _tnfs_tcp_send(m_info, pkt, payload_size);
}
else
{
#ifdef TNFS_UDP_SIMULATE_SEND_LOSS
if (rand() < TNFS_UDP_SIMULATE_SEND_LOSS_PROB * RAND_MAX) {
Debug_println("TNFS_UDP_SIMULATE: send loss");
return true;
}
#endif
#ifdef TNFS_UDP_SIMULATE_SEND_TWICE
if (rand() < TNFS_UDP_SIMULATE_SEND_TWICE_PROB * RAND_MAX) {
Debug_println("TNFS_UDP_SIMULATE: send twice");
_tnfs_udp_send(udp, m_info, pkt, payload_size);
}
#endif
return _tnfs_udp_send(udp, m_info, pkt, payload_size);
}
}

bool _tnfs_udp_send(fnUDP *udp, tnfsMountInfo *m_info, tnfsPacket &pkt, uint16_t payload_size)
bool _tnfs_tcp_send(tnfsMountInfo *m_info, tnfsPacket &pkt, uint16_t payload_size)
{
bool sent;
// Use the IP address if we have it
fnTcpClient *tcp = &m_info->tcp_client;
if (!tcp->connected())
{
bool success = false;
if (m_info->host_ip != IPADDR_NONE)
sent = udp->beginPacket(m_info->host_ip, m_info->port);
success = tcp->connect(m_info->host_ip, m_info->port, TNFS_TIMEOUT);
else
sent = udp->beginPacket(m_info->hostname, m_info->port);

if (sent)
success = tcp->connect(m_info->hostname, m_info->port, TNFS_TIMEOUT);
if (!success)
{
udp->write(pkt.rawData, payload_size + TNFS_HEADER_SIZE); // Add the data payload along with 4 bytes of TNFS header
sent = udp->endPacket();
Debug_println("Can't connect to the TCP server");
return false;
}
return sent;
}
int l = tcp->write(pkt.rawData, payload_size + TNFS_HEADER_SIZE);
return l == payload_size + TNFS_HEADER_SIZE;
}

#ifndef TNFS_UDP_SIMULATE_POOR_CONNECTION
bool _tnfs_udp_send(fnUDP *udp, tnfsMountInfo *m_info, tnfsPacket &pkt, uint16_t payload_size)
{
return _tnfs_udp_do_send(udp, m_info, pkt, payload_size);
}
#endif

bool _tnfs_udp_do_send(fnUDP *udp, tnfsMountInfo *m_info, tnfsPacket &pkt, uint16_t payload_size)
{
bool sent;
// Use the IP address if we have it
if (m_info->host_ip != IPADDR_NONE)
sent = udp->beginPacket(m_info->host_ip, m_info->port);
else
sent = udp->beginPacket(m_info->hostname, m_info->port);

if (sent)
{
udp->write(pkt.rawData, payload_size + TNFS_HEADER_SIZE); // Add the data payload along with 4 bytes of TNFS header
sent = udp->endPacket();
}
return sent;
}

/*
Expand All @@ -1323,49 +1330,40 @@ int _tnfs_recv(fnUDP *udp, tnfsMountInfo *m_info, tnfsPacket &pkt)
{
if (m_info->protocol == TNFS_PROTOCOL_TCP || m_info->protocol == TNFS_PROTOCOL_UNKNOWN)
{
fnTcpClient *tcp = &m_info->tcp_client;
if (!tcp->connected())
{
return -1;
}
if (!tcp->available())
{
return -1;
}
return tcp->read(pkt.rawData, sizeof(pkt.rawData));
return _tnfs_tcp_recv(m_info, pkt);
}
else
{
#ifdef TNFS_UDP_SIMULATE_RECV_TWICE
if (m_info->last_packet_len >= 0 && rand() < TNFS_UDP_SIMULATE_RECV_TWICE_PROB * RAND_MAX) {
Debug_println("TNFS_UDP_SIMULATE: recv twice");
memcpy(pkt.rawData, m_info->last_packet, sizeof(pkt.rawData));
int len = m_info->last_packet_len;
m_info->last_packet_len = -1;
return len;
}
#endif
if (!udp->parsePacket())
{
return -1;
}
#ifdef TNFS_UDP_SIMULATE_RECV_LOSS
if (rand() < TNFS_UDP_SIMULATE_RECV_LOSS_PROB * RAND_MAX) {
Debug_println("TNFS_UDP_SIMULATE: recv loss");
tnfsPacket lostPkt;
udp->read(lostPkt.rawData, sizeof(pkt.rawData));
return -1;
}
#endif
int len = udp->read(pkt.rawData, sizeof(pkt.rawData));
#ifdef TNFS_UDP_SIMULATE_RECV_TWICE
memcpy(m_info->last_packet, pkt.rawData, sizeof(m_info->last_packet));
m_info->last_packet_len = len;
#endif
return len;
return _tnfs_udp_recv(udp, m_info, pkt);
}
}

int _tnfs_tcp_recv(tnfsMountInfo *m_info, tnfsPacket &pkt)
{
fnTcpClient *tcp = &m_info->tcp_client;
if (!tcp->connected())
{
return -1;
}
if (!tcp->available())
{
return -1;
}
return tcp->read(pkt.rawData, sizeof(pkt.rawData));
}

#ifndef TNFS_UDP_SIMULATE_POOR_CONNECTION
int _tnfs_udp_recv(fnUDP *udp, tnfsMountInfo *m_info, tnfsPacket &pkt)
{
if (!udp->parsePacket())
{
return -1;
}
int len = udp->read(pkt.rawData, sizeof(pkt.rawData));
return len;
}
#endif

/*
Send constructed TNFS packet and check for reply
The send/receive loop will be attempted tnfsPacket.max_retries times (default: TNFS_RETRIES)
Expand Down
12 changes: 12 additions & 0 deletions lib/TNFSlib/tnfslib_udp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef _TNFSLIB_UDP_H
#define _TNFSLIB_UDP_H

#include "tnfslib.h"
#include "fnUDP.h"

bool _tnfs_udp_send(fnUDP *udp, tnfsMountInfo *m_info, tnfsPacket &pkt, uint16_t payload_size);
int _tnfs_udp_recv(fnUDP *udp, tnfsMountInfo *m_info, tnfsPacket &pkt);

bool _tnfs_udp_do_send(fnUDP *udp, tnfsMountInfo *m_info, tnfsPacket &pkt, uint16_t payload_size);

#endif
53 changes: 53 additions & 0 deletions lib/TNFSlib/tnfslib_udp_testing.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include "tnfslib_udp.h"
#include "tnfslibMountInfo.h"
#include "../../include/debug.h"

#ifdef TNFS_UDP_SIMULATE_POOR_CONNECTION
bool _tnfs_udp_send(fnUDP *udp, tnfsMountInfo *m_info, tnfsPacket &pkt, uint16_t payload_size)
{
#ifdef TNFS_UDP_SIMULATE_SEND_LOSS
if (rand() < TNFS_UDP_SIMULATE_SEND_LOSS_PROB * RAND_MAX) {
Debug_println("TNFS_UDP_SIMULATE: send loss");
return true;
}
#endif
#ifdef TNFS_UDP_SIMULATE_SEND_TWICE
if (rand() < TNFS_UDP_SIMULATE_SEND_TWICE_PROB * RAND_MAX) {
Debug_println("TNFS_UDP_SIMULATE: send twice");
_tnfs_udp_do_send(udp, m_info, pkt, payload_size);
}
#endif
return _tnfs_udp_do_send(udp, m_info, pkt, payload_size);
}

int _tnfs_udp_recv(fnUDP *udp, tnfsMountInfo *m_info, tnfsPacket &pkt)
{
#ifdef TNFS_UDP_SIMULATE_RECV_TWICE
if (m_info->last_packet_len >= 0 && rand() < TNFS_UDP_SIMULATE_RECV_TWICE_PROB * RAND_MAX) {
Debug_println("TNFS_UDP_SIMULATE: recv twice");
memcpy(pkt.rawData, m_info->last_packet, sizeof(pkt.rawData));
int len = m_info->last_packet_len;
m_info->last_packet_len = -1;
return len;
}
#endif
if (!udp->parsePacket())
{
return -1;
}
#ifdef TNFS_UDP_SIMULATE_RECV_LOSS
if (rand() < TNFS_UDP_SIMULATE_RECV_LOSS_PROB * RAND_MAX) {
Debug_println("TNFS_UDP_SIMULATE: recv loss");
tnfsPacket lostPkt;
udp->read(lostPkt.rawData, sizeof(pkt.rawData));
return -1;
}
#endif
int len = udp->read(pkt.rawData, sizeof(pkt.rawData));
#ifdef TNFS_UDP_SIMULATE_RECV_TWICE
memcpy(m_info->last_packet, pkt.rawData, sizeof(m_info->last_packet));
m_info->last_packet_len = len;
#endif
return len;
}
#endif

0 comments on commit 083956f

Please sign in to comment.