#include "util/container.h"
#include "util/thread.h"
#include "util/numeric.h"
+#include "networkprotocol.h"
#include <iostream>
#include <fstream>
#include <list>
};
// This adds the base headers to the data and makes a packet out of it
-BufferedPacket makePacket(Address &address, SharedBuffer<u8> data,
- u32 protocol_id, u16 sender_peer_id, u8 channel);
+BufferedPacket makePacket(Address &address, const SharedBuffer<u8> &data,
+ u32 protocol_id, session_t sender_peer_id, u8 channel);
// Depending on size, make a TYPE_ORIGINAL or TYPE_SPLIT packet
// Increments split_seqnum if a split packet is made
-void makeAutoSplitPacket(SharedBuffer<u8> data, u32 chunksize_max,
+void makeAutoSplitPacket(const SharedBuffer<u8> &data, u32 chunksize_max,
u16 &split_seqnum, std::list<SharedBuffer<u8>> *list);
// Add the TYPE_RELIABLE header to the data
-SharedBuffer<u8> makeReliablePacket(SharedBuffer<u8> data, u16 seqnum);
+SharedBuffer<u8> makeReliablePacket(const SharedBuffer<u8> &data, u16 seqnum);
struct IncomingSplitPacket
{
IncomingSplitPacket() = delete;
- // Key is chunk number, value is data without headers
- std::map<u16, SharedBuffer<u8>> chunks;
- u32 chunk_count;
float time = 0.0f; // Seconds from adding
- bool reliable = false; // If true, isn't deleted on timeout
+ u32 chunk_count;
+ bool reliable; // If true, isn't deleted on timeout
bool allReceived() const
{
return (chunks.size() == chunk_count);
}
+ bool insert(u32 chunk_num, SharedBuffer<u8> &chunkdata);
+ SharedBuffer<u8> reassemble();
+
+private:
+ // Key is chunk number, value is data without headers
+ std::map<u16, SharedBuffer<u8>> chunks;
};
/*
TODO: Should we have a receiver_peer_id also?
Header (7 bytes):
[0] u32 protocol_id
- [4] u16 sender_peer_id
+ [4] session_t sender_peer_id
[6] u8 channel
sender_peer_id:
Unique to each peer.
CONTROLTYPE_ACK
[2] u16 seqnum
CONTROLTYPE_SET_PEER_ID
- [2] u16 peer_id_new
+ [2] session_t peer_id_new
CONTROLTYPE_PING
- There is no actual reply, but this can be sent in a reliable
packet to get a reply
#define CONTROLTYPE_SET_PEER_ID 1
#define CONTROLTYPE_PING 2
#define CONTROLTYPE_DISCO 3
-#define CONTROLTYPE_ENABLE_BIG_SEND_WINDOW 4
/*
ORIGINAL: This is a plain packet with no control and no error
BufferedPacket popFirst();
BufferedPacket popSeqnum(u16 seqnum);
- void insert(BufferedPacket &p,u16 next_expected);
+ void insert(BufferedPacket &p, u16 next_expected);
void incrementTimeouts(float dtime);
std::list<BufferedPacket> getTimedOuts(float timeout,
void print();
bool empty();
- bool containsPacket(u16 seqnum);
RPBSearchResult notFound();
u32 size();
private:
- RPBSearchResult findPacket(u16 seqnum);
+ RPBSearchResult findPacket(u16 seqnum); // does not perform locking
std::list<BufferedPacket> m_list;
- u32 m_list_size = 0;
u16 m_oldest_non_answered_ack;
struct OutgoingPacket
{
- u16 peer_id;
+ session_t peer_id;
u8 channelnum;
SharedBuffer<u8> data;
bool reliable;
bool ack;
- OutgoingPacket(u16 peer_id_, u8 channelnum_, const SharedBuffer<u8> &data_,
+ OutgoingPacket(session_t peer_id_, u8 channelnum_, const SharedBuffer<u8> &data_,
bool reliable_,bool ack_=false):
peer_id(peer_id_),
channelnum(channelnum_),
CONNCMD_SEND,
CONNCMD_SEND_TO_ALL,
CONCMD_ACK,
- CONCMD_CREATE_PEER,
- CONCMD_DISABLE_LEGACY
+ CONCMD_CREATE_PEER
};
struct ConnectionCommand
{
enum ConnectionCommandType type = CONNCMD_NONE;
Address address;
- u16 peer_id = PEER_ID_INEXISTENT;
+ session_t peer_id = PEER_ID_INEXISTENT;
u8 channelnum = 0;
- SharedBuffer<u8> data;
+ Buffer<u8> data;
bool reliable = false;
bool raw = false;
ConnectionCommand() = default;
+ ConnectionCommand &operator=(const ConnectionCommand &other)
+ {
+ type = other.type;
+ address = other.address;
+ peer_id = other.peer_id;
+ channelnum = other.channelnum;
+ // We must copy the buffer here to prevent race condition
+ data = SharedBuffer<u8>(*other.data, other.data.getSize());
+ reliable = other.reliable;
+ raw = other.raw;
+ return *this;
+ }
void serve(Address address_)
{
{
type = CONNCMD_DISCONNECT;
}
- void disconnect_peer(u16 peer_id_)
+ void disconnect_peer(session_t peer_id_)
{
type = CONNCMD_DISCONNECT_PEER;
peer_id = peer_id_;
}
- void send(u16 peer_id_, u8 channelnum_, NetworkPacket* pkt, bool reliable_);
+ void send(session_t peer_id_, u8 channelnum_, NetworkPacket *pkt, bool reliable_);
- void ack(u16 peer_id_, u8 channelnum_, const SharedBuffer<u8> &data_)
+ void ack(session_t peer_id_, u8 channelnum_, const SharedBuffer<u8> &data_)
{
type = CONCMD_ACK;
peer_id = peer_id_;
reliable = false;
}
- void createPeer(u16 peer_id_, const SharedBuffer<u8> &data_)
+ void createPeer(session_t peer_id_, const SharedBuffer<u8> &data_)
{
type = CONCMD_CREATE_PEER;
peer_id = peer_id_;
reliable = true;
raw = true;
}
-
- void disableLegacy(u16 peer_id_, const SharedBuffer<u8> &data_)
- {
- type = CONCMD_DISABLE_LEGACY;
- peer_id = peer_id_;
- data = data_;
- channelnum = 0;
- reliable = true;
- raw = true;
- }
};
/* maximum window size to use, 0xFFFF is theoretical maximum don't think about
void UpdateBytesLost(unsigned int bytes);
void UpdateBytesReceived(unsigned int bytes);
- void UpdateTimers(float dtime, bool legacy_peer);
+ void UpdateTimers(float dtime);
const float getCurrentDownloadRateKB()
{ MutexAutoLock lock(m_internal_mutex); return cur_kbps; };
unsigned int current_packet_loss = 0;
unsigned int current_packet_too_late = 0;
- unsigned int current_packet_successfull = 0;
+ unsigned int current_packet_successful = 0;
float packet_loss_counter = 0.0f;
unsigned int current_bytes_transfered = 0;
bool getAddress(MTProtocols type, Address& toset);
- void setNonLegacyPeer();
-
- bool getLegacyPeer()
- { return m_legacy_peer; }
-
u16 getNextSplitSequenceNumber(u8 channel);
void setNextSplitSequenceNumber(u8 channel, u16 seqnum);
bool processReliableSendCommand(
ConnectionCommand &c,
unsigned int max_packet_size);
-
- bool m_legacy_peer = true;
};
/*
struct ConnectionEvent
{
enum ConnectionEventType type = CONNEVENT_NONE;
- u16 peer_id = 0;
+ session_t peer_id = 0;
Buffer<u8> data;
bool timeout = false;
Address address;
return "Invalid ConnectionEvent";
}
- void dataReceived(u16 peer_id_, const SharedBuffer<u8> &data_)
+ void dataReceived(session_t peer_id_, const SharedBuffer<u8> &data_)
{
type = CONNEVENT_DATA_RECEIVED;
peer_id = peer_id_;
data = data_;
}
- void peerAdded(u16 peer_id_, Address address_)
+ void peerAdded(session_t peer_id_, Address address_)
{
type = CONNEVENT_PEER_ADDED;
peer_id = peer_id_;
address = address_;
}
- void peerRemoved(u16 peer_id_, bool timeout_, Address address_)
+ void peerRemoved(session_t peer_id_, bool timeout_, Address address_)
{
type = CONNEVENT_PEER_REMOVED;
peer_id = peer_id_;
bool Connected();
void Disconnect();
void Receive(NetworkPacket* pkt);
- void Send(u16 peer_id, u8 channelnum, NetworkPacket* pkt, bool reliable);
- u16 GetPeerID() { return m_peer_id; }
- Address GetPeerAddress(u16 peer_id);
- float getPeerStat(u16 peer_id, rtt_stat_type type);
+ void Send(session_t peer_id, u8 channelnum, NetworkPacket *pkt, bool reliable);
+ session_t GetPeerID() const { return m_peer_id; }
+ Address GetPeerAddress(session_t peer_id);
+ float getPeerStat(session_t peer_id, rtt_stat_type type);
float getLocalStat(rate_stat_type type);
const u32 GetProtocolID() const { return m_protocol_id; };
const std::string getDesc();
- void DisconnectPeer(u16 peer_id);
+ void DisconnectPeer(session_t peer_id);
protected:
- PeerHelper getPeerNoEx(u16 peer_id);
+ PeerHelper getPeerNoEx(session_t peer_id);
u16 lookupPeer(Address& sender);
u16 createPeer(Address& sender, MTProtocols protocol, int fd);
UDPPeer* createServerPeer(Address& sender);
- bool deletePeer(u16 peer_id, bool timeout);
+ bool deletePeer(session_t peer_id, bool timeout);
- void SetPeerID(u16 id) { m_peer_id = id; }
+ void SetPeerID(session_t id) { m_peer_id = id; }
- void sendAck(u16 peer_id, u8 channelnum, u16 seqnum);
+ void sendAck(session_t peer_id, u8 channelnum, u16 seqnum);
void PrintInfo(std::ostream &out);
- std::list<u16> getPeerIDs()
+ std::list<session_t> getPeerIDs()
{
MutexAutoLock peerlock(m_peers_mutex);
return m_peer_ids;
void TriggerSend();
private:
- std::list<Peer*> getPeers();
-
MutexedQueue<ConnectionEvent> m_event_queue;
- u16 m_peer_id = 0;
+ session_t m_peer_id = 0;
u32 m_protocol_id;
- std::map<u16, Peer*> m_peers;
- std::list<u16> m_peer_ids;
+ std::map<session_t, Peer *> m_peers;
+ std::list<session_t> m_peer_ids;
std::mutex m_peers_mutex;
std::unique_ptr<ConnectionSendThread> m_sendThread;
bool m_shutting_down = false;
- u16 m_next_remote_peer_id = 2;
+ session_t m_next_remote_peer_id = 2;
};
} // namespace