39 memset(
this, 0,
sizeof(*
this));
69 os.setf(std::ios::fixed,std::ios::floatfield);
100 : timeout_(
senf::
ClockService::seconds(20)), interface_(interface), qAlgo_( new
senf::
ppi::NoneQueueingAlgorithm()),
126 if (
SENF_UNLIKELY((thdr.
size() < (TunnelHeaderPacket::Parser::fixed_bytes + senf::EthernetPacketParser::fixed_bytes)) or
135 v_handleCtrlPacket( eth, addr, handle);
143 signed diff = v_processSequenceNumber(thdr, addr);
150 q.snr = q.rssi - q.noise;
151 q.flags.frameLength = eth.size();
156 else if ( diff == 0) {
157 q.flags.frameDuplicate =
true;
162 q.flags.frameReordered =
true;
169 auto extOUI (VLanId::payload<EthOUIExtensionPacket>(eth));
189 handle.writeto(txInfo.first,pkt.prev().data());
214 if (!qAlgo_->empty()) {
221 for (
auto & frag : fragmenter_.
fragments()) {
222 if (!force and !qAlgo_->enqueue(frag, force)) {
233 if (handle.writeable()) {
244 for (
auto & frag : fragmenter_.
fragments()) {
245 if (handle.writeable()) {
259 while (handle.writeable() and qAlgo_->peek()) {
269 return v_writePacket( handle, packet);
276 ctrlPacket->code() << code;
284 eth->source( interface_.
id())
285 ->destination( dstMAC);
287 ethOUIExt.append(ctrlPacket);
312 qAlgo_.reset(qAlgorithm.release());
323 os <<
"Id: " << interface_.
id() << std::endl
324 <<
"Enabled: " << (interface_.
enabled() ?
"yes" :
"no") << std::endl
326 os <<
"IOStats: " << stats_.
stats().
dump() << std::endl;
327 os <<
"qAlgo.size: " << qAlgo_->size() << std::endl;
339 clients_by_lastSeen_(clients_.get<ByLastSeen>()),
340 clients_by_macAddr_(clients_.get<ByMACAddr>()),
341 clients_by_inetAddr_(clients_.get<ByINetAddr>()),
349 for (Clients_by_macAddr::iterator client = clients_by_macAddr_.begin(); client != clients_by_macAddr_.end(); client++) {
350 sendPkt(handle, client->macAddr, eth.clone());
354 Clients_by_macAddr::iterator client (clients_by_macAddr_.find(dst));
355 if (client != clients_by_macAddr_.end()) {
356 return sendPkt(handle, client->macAddr, eth);
368 if (client != clients_by_macAddr_.end()) {
369 thdr->sequenceNumber() = client->txSeqNo;
373 thdr->sequenceNumber() = 0;
382 if (
SENF_LIKELY(client != clients_by_macAddr_.end())) {
383 return std::make_pair(client->inetAddr, client->fragmentationThreshold);
392 Clients_by_inetAddr::iterator client (clients_by_inetAddr_.find(srcAddr));
394 if (
SENF_LIKELY(client != clients_by_inetAddr_.end())) {
413 prefix_ void senf::emu::detail::TunnelServerController::v_handleCtrlPacket(
417 Clients_by_macAddr::iterator clientByMAC (clients_by_macAddr_.find(ethPacket->source()));
418 Clients_by_inetAddr::iterator clientByINet (clients_by_inetAddr_.find(srcAddr));
419 unsigned responseCode (ctrlPacket->code() + 1);
420 bool updateLastSeen (
false);
421 bool updateINetAddr (
false);
423 switch (ctrlPacket->code()) {
425 if (! ctrlPacket->has_capacity()) {
430 if (clientByMAC == clients_by_macAddr_.end()) {
431 if (clientByINet == clients_by_inetAddr_.end()) {
433 clientByMAC = clients_by_macAddr_.insert( TunnelClient(ethPacket->source(), srcAddr)).first;
434 updateLastSeen =
true;
440 if (clientByINet == clients_by_inetAddr_.end()) {
442 updateINetAddr =
true;
445 updateLastSeen =
true;
454 if (clientByMAC == clients_by_macAddr_.end()) {
458 if (clientByINet == clients_by_inetAddr_.end()) {
460 updateINetAddr =
true;
463 updateLastSeen =
true;
468 if (clientByMAC != clients_by_macAddr_.end() && clientByINet != clients_by_inetAddr_.end())
470 clients_by_macAddr_.erase( clientByMAC);
486 if (updateLastSeen) {
493 if (responseCode != 0)
497 prefix_ void senf::emu::detail::TunnelServerController::processTimeout()
499 SENF_ASSERT( !clients_.empty(),
"empty client map in TunnelServerController::processTimeout");
501 Clients_by_lastSeen::iterator client (clients_by_lastSeen_.begin());
503 << client->macAddr <<
", " << client->inetAddr <<
") last seen " <<
505 clients_by_lastSeen_.erase( client);
510 prefix_ void senf::emu::detail::TunnelServerController::resetTimer()
512 if (clients_.empty())
515 timer_.
timeout(clients_by_lastSeen_.begin()->lastSeen +
timeout());
520 for (TunnelClient
const & client : clients_) {
527 senf::emu::tunnel::Capacity::const_iterator i (capacity.find(direction));
528 return i != capacity.end() ? i->second : 0;
535 Clients_by_macAddr::const_iterator client (clients_by_macAddr_.find(clientAddr));
536 return client != clients_by_macAddr_.end() ?
get(client->capacity, direction) : 0;
544 Clients_by_macAddr::const_iterator client (clients_by_macAddr_.find(clientAddr));
545 if ( client != clients_by_macAddr_.end()) {
548 for (
auto it = clients_by_macAddr_.begin(); it != clients_by_macAddr_.end(); it++) {
557 Clients_by_macAddr::const_iterator client (clients_by_macAddr_.find(clientAddr));
558 return client != clients_by_macAddr_.end() ? (client->fragmentationThreshold) : 0;
562 prefix_ void senf::emu::detail::TunnelServerController::v_dumpInfo(std::ostream & os)
566 if (clients_.empty()) {
567 os <<
" none" << std::endl;
571 boost::format fmtClient (
"%-30s %-17s %4d %9d %4s %18d %18d %5x %5x %7d");
572 os << fmtClient %
"address" %
"MAC address" %
"FragThesh" %
"last seen" %
"" %
"capacity_to_client" %
"capacity_from_client" %
"TxSeq" %
"RxSeq" %
"ReSyncs"<< std::endl;
573 for (TunnelClient
const & client : clients_) {
575 % senf::str(client.inetAddr)
576 % senf::str(client.macAddr)
577 % senf::str(client.fragmentationThreshold)
594 interface_(interface), established_(false),
598 rxSeqNo_(0xffffffff),
617 rxSeqNo_ = thdr->sequenceNumber();
622 reordered_ += diff < 0;
623 duplicate_ += diff == 0;
628 prefix_ void senf::emu::detail::TunnelClientController::v_handleCtrlPacket(
632 SENF_LOG((
"skipping control Packet from unknown server " << srcAddr));
635 serverLastSeen_ = senf::scheduler::now();
637 switch (ctrlPacket->code()) {
640 serverMAC_ = ethPacket->source();
649 established_ =
false;
668 return sendPkt( handle, serverMAC_, eth);
678 thdr->sequenceNumber() = txSeqNo_;
679 txSeqNo_ = (txSeqNo_ + 1) % 0x20000;
681 thdr->sequenceNumber() = 0;
689 return std::make_pair(serverINet_, fragmentationThreshold_);
692 prefix_ void senf::emu::detail::TunnelClientController::processTimeout()
696 if (scheduler::now() - serverLastSeen_ <
timeout()) {
701 established_ =
false;
705 rxSeqNo_ = 0xFFFFFFFF;
711 if (serverINet_ && interface_.
enabled())
715 prefix_ void senf::emu::detail::TunnelClientController::sendSetupRequest()
718 setupRequest->add_capacity();
734 established_ =
false;
739 established_ =
false;
747 rxSeqNo_ = 0xFFFFFFFF;
754 serverINet_ = address;
769 fragmentationThreshold_ = ft;
775 return fragmentationThreshold_;
778 prefix_ void senf::emu::detail::TunnelClientController::v_timeoutChanged()
783 prefix_ void senf::emu::detail::TunnelClientController::v_dumpInfo(std::ostream & os)
787 <<
"Connection established: " << (established_ ?
"yes" :
"no") << std::endl
788 <<
"Server address: " << serverINet_ << std::endl
789 <<
"Server MACAddress: " << serverMAC_ << std::endl
790 <<
"Server last seen: " 792 <<
" sec." << std::endl
795 <<
"setupREQs sent " << setupRequests_ << std::endl
796 <<
"txSeqNo: 0x" << std::hex << txSeqNo_ <<
", rxSeqno 0x" << rxSeqNo_ << std::dec <<
", reSyncs " << reSyncs_ << std::endl
797 <<
"reordered: " << reordered_ <<
", duplicate: " << duplicate_ << std::endl;
TunnelControlPacket public header.
unsigned capacity(tunnel::CapacityDirection direction) const
config::time_type clock_type
static MACAddress const None
bool processFrame(senf::EthernetPacket const ð, EthernetFragmentPacket const &fragment)
bool sendPkt(Handle &handle, MACAddress const &dstMAC, senf::EthernetPacket pkt)
static const unsigned TunnelOverhead
virtual std::pair< INet6SocketAddress, unsigned > v_getTxInfo(Packet const ð) const =0
TunnelController internal header.
static SENF_CLOCKSERVICE_CONSTEXPR int64_type in_milliseconds(clock_type const &v)
static ConcretePacket createBefore(Packet const &packet)
std::map< CapacityDirection, unsigned > Capacity
Incoming or outgoing interface.
bool enabled() const
true, if interface enabled
ClockService::clock_type timeout() const
PacketType readPacket(Handle &handle)
TunnelServerController(TunnelServerInterface &interface)
TunnelIOStatistics stats()
void id(MACAddress const &eui)
Change interface MAC.
boost::function< R(Args)> membind(R(T::*fn)(Args), T *ob)
void v_prependTHdr(EthernetPacket ð) override
TunnelControllerBase(TunnelInterfaceBase &interface)
PacketData & data() const
std::unique_ptr< QueueingAlgorithm > ptr
unsigned fragmentationThreshold() const
void sendCtrlPacket(Handle &handle, MACAddress const &dstMAC, boost::uint8_t code)
void v_prependTHdr(EthernetPacket ð) override
static SENF_CLOCKSERVICE_CONSTEXPR clock_type milliseconds(int64_type const &v)
senf::ClockService::clock_type tstamp
void dumpInfo(std::ostream &os)
void timeout(ClockService::clock_type const &timeout, bool initiallyEnabled=true)
std::vector< senf::EthernetPacket > & fragments()
Incoming packet timestamp.
std::pair< INet6SocketAddress, unsigned > v_getTxInfo(Packet const ð) const override
static std::uint16_t payloadTypeLength(senf::EthernetPacket const ð)
senf::Detail::DifferenceSigned seqNoDiff_
senf::EthernetPacket & reassembledPacket()
unsigned fragmentationThreshold(MACAddress const &clientAddr) const
UDPv6ClientSocketHandle Handle
void fragmentFrame(senf::EthernetPacket const &pkt, unsigned treshold)
bool writePacket(Handle &handle, PacketType packet)
static const EtherTypes::key_t etherType
Annotation & annotation()
std::pair< INet6SocketAddress, unsigned > v_getTxInfo(Packet const ð) const override
void do_sendPkt(Handle &handle, senf::EthernetPacket &pkt, std::pair< senf::INet6SocketAddress, unsigned > const &txInfo)
static ConcretePacket create()
ConcretePacket< EthOUIExtensionPacketType > EthOUIExtensionPacket
TunnelClientController(TunnelClientInterface &interface)
#define SENF_ASSERT(x, comment)
unsigned capacity(MACAddress const &clientAddr, tunnel::CapacityDirection direction) const
unsigned fragmentationCount()
unsigned fragmentationCount()
void terminateAllClients(Handle handle)
void flushQueue(Handle &handle)
ppi::QueueingAlgorithm & qAlgorithm() const
EthernetPacket PacketType
unsigned packetsReassembled()
static SENF_CLOCKSERVICE_CONSTEXPR int64_type in_seconds(clock_type const &v)
virtual void v_prependTHdr(EthernetPacket ð)=0
TunnelInterface public header.
ConcretePacket< EthernetPacketType > EthernetPacket
senf::ClockService::clock_type duration() const
static INet6Address const None
static bool isTunnelCtrlPacket(EthernetPacket const ð)
static MACAddress const Broadcast
std::int32_t difference(std::uint32_t current, std::uint32_t last)
INet6SocketAddress const & serverAddress() const
void dump(std::ostream &os) const
static bool fragmentationRequired(senf::EthernetPacket const &pkt, unsigned threshold)