mirror of
https://github.com/genodelabs/genode.git
synced 2025-03-11 06:54:18 +00:00
214 lines
5.0 KiB
C
214 lines
5.0 KiB
C
|
/*
|
||
|
* \brief State tracking for UDP/TCP connections
|
||
|
* \author Martin Stein
|
||
|
* \date 2016-08-19
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* Copyright (C) 2016 Genode Labs GmbH
|
||
|
*
|
||
|
* This file is part of the Genode OS framework, which is distributed
|
||
|
* under the terms of the GNU General Public License version 2.
|
||
|
*/
|
||
|
|
||
|
#ifndef _LINK_H_
|
||
|
#define _LINK_H_
|
||
|
|
||
|
/* Genode includes */
|
||
|
#include <os/timer.h>
|
||
|
#include <util/avl_tree.h>
|
||
|
#include <util/list.h>
|
||
|
#include <net/ipv4.h>
|
||
|
|
||
|
/* local includes */
|
||
|
#include <pointer.h>
|
||
|
|
||
|
namespace Net {
|
||
|
|
||
|
class Configuration;
|
||
|
class Port_allocator_guard;
|
||
|
class Tcp_packet;
|
||
|
class Interface;
|
||
|
class Link_side_id;
|
||
|
class Link_side;
|
||
|
class Link_side_tree;
|
||
|
class Link;
|
||
|
struct Link_list : Genode::List<Link> { };
|
||
|
class Tcp_link;
|
||
|
class Udp_link;
|
||
|
}
|
||
|
|
||
|
|
||
|
struct Net::Link_side_id
|
||
|
{
|
||
|
int const data[];
|
||
|
Ipv4_address const src_ip;
|
||
|
Genode::uint16_t const src_port;
|
||
|
Ipv4_address const dst_ip;
|
||
|
Genode::uint16_t const dst_port;
|
||
|
|
||
|
static constexpr Genode::size_t data_size();
|
||
|
|
||
|
|
||
|
/************************
|
||
|
** Standard operators **
|
||
|
************************/
|
||
|
|
||
|
bool operator == (Link_side_id const &id) const;
|
||
|
|
||
|
bool operator > (Link_side_id const &id) const;
|
||
|
}
|
||
|
__attribute__((__packed__));
|
||
|
|
||
|
|
||
|
class Net::Link_side : public Genode::Avl_node<Link_side>
|
||
|
{
|
||
|
friend class Link;
|
||
|
|
||
|
private:
|
||
|
|
||
|
Interface &_interface;
|
||
|
Link_side_id const _id;
|
||
|
Link &_link;
|
||
|
|
||
|
public:
|
||
|
|
||
|
Link_side(Interface &interface,
|
||
|
Link_side_id const &id,
|
||
|
Link &link);
|
||
|
|
||
|
Link_side const &find_by_id(Link_side_id const &id) const;
|
||
|
|
||
|
bool is_client() const;
|
||
|
|
||
|
|
||
|
/**************
|
||
|
** Avl_node **
|
||
|
**************/
|
||
|
|
||
|
bool higher(Link_side *side) { return side->_id > _id; }
|
||
|
|
||
|
|
||
|
/*********
|
||
|
** Log **
|
||
|
*********/
|
||
|
|
||
|
void print(Genode::Output &output) const;
|
||
|
|
||
|
|
||
|
/***************
|
||
|
** Accessors **
|
||
|
***************/
|
||
|
|
||
|
Interface &interface() const { return _interface; }
|
||
|
Link &link() const { return _link; }
|
||
|
Ipv4_address const &src_ip() const { return _id.src_ip; }
|
||
|
Ipv4_address const &dst_ip() const { return _id.dst_ip; }
|
||
|
Genode::uint16_t src_port() const { return _id.src_port; }
|
||
|
Genode::uint16_t dst_port() const { return _id.dst_port; }
|
||
|
};
|
||
|
|
||
|
|
||
|
struct Net::Link_side_tree : Genode::Avl_tree<Link_side>
|
||
|
{
|
||
|
struct No_match : Genode::Exception { };
|
||
|
|
||
|
Link_side const &find_by_id(Link_side_id const &id) const;
|
||
|
};
|
||
|
|
||
|
|
||
|
class Net::Link : public Link_list::Element
|
||
|
{
|
||
|
protected:
|
||
|
|
||
|
using Signal_handler = Genode::Signal_handler<Link>;
|
||
|
|
||
|
Configuration &_config;
|
||
|
Link_side _client;
|
||
|
Pointer<Port_allocator_guard> const _server_port_alloc;
|
||
|
Link_side _server;
|
||
|
Genode::One_shot_timeout<Link> _close_timeout;
|
||
|
Genode::Timer::Microseconds const _close_timeout_us;
|
||
|
Genode::uint8_t const _protocol;
|
||
|
|
||
|
void _handle_close_timeout(Genode::Timer::Microseconds);
|
||
|
|
||
|
void _packet() { _close_timeout.start(_close_timeout_us); }
|
||
|
|
||
|
public:
|
||
|
|
||
|
struct No_port_allocator : Genode::Exception { };
|
||
|
|
||
|
Link(Interface &cln_interface,
|
||
|
Link_side_id const &cln_id,
|
||
|
Pointer<Port_allocator_guard> const srv_port_alloc,
|
||
|
Interface &srv_interface,
|
||
|
Link_side_id const &srv_id,
|
||
|
Genode::Timer &timer,
|
||
|
Configuration &config,
|
||
|
Genode::uint8_t const protocol);
|
||
|
|
||
|
void dissolve();
|
||
|
|
||
|
|
||
|
/*********
|
||
|
** Log **
|
||
|
*********/
|
||
|
|
||
|
void print(Genode::Output &output) const;
|
||
|
|
||
|
|
||
|
/***************
|
||
|
** Accessors **
|
||
|
***************/
|
||
|
|
||
|
Link_side &client() { return _client; }
|
||
|
Link_side &server() { return _server; }
|
||
|
};
|
||
|
|
||
|
|
||
|
class Net::Tcp_link : public Link
|
||
|
{
|
||
|
private:
|
||
|
|
||
|
bool _client_fin = false;
|
||
|
bool _server_fin = false;
|
||
|
bool _client_fin_acked = false;
|
||
|
bool _server_fin_acked = false;
|
||
|
bool _closed = false;
|
||
|
|
||
|
void _fin_acked();
|
||
|
|
||
|
public:
|
||
|
|
||
|
Tcp_link(Interface &cln_interface,
|
||
|
Link_side_id const &cln_id,
|
||
|
Pointer<Port_allocator_guard> const srv_port_alloc,
|
||
|
Interface &srv_interface,
|
||
|
Link_side_id const &srv_id,
|
||
|
Genode::Timer &timer,
|
||
|
Configuration &config,
|
||
|
Genode::uint8_t const protocol);
|
||
|
|
||
|
void client_packet(Tcp_packet &tcp);
|
||
|
|
||
|
void server_packet(Tcp_packet &tcp);
|
||
|
};
|
||
|
|
||
|
|
||
|
struct Net::Udp_link : Link
|
||
|
{
|
||
|
Udp_link(Interface &cln_interface,
|
||
|
Link_side_id const &cln_id,
|
||
|
Pointer<Port_allocator_guard> const srv_port_alloc,
|
||
|
Interface &srv_interface,
|
||
|
Link_side_id const &srv_id,
|
||
|
Genode::Timer &timer,
|
||
|
Configuration &config,
|
||
|
Genode::uint8_t const protocol);
|
||
|
|
||
|
void packet() { _packet(); }
|
||
|
};
|
||
|
|
||
|
#endif /* _LINK_H_ */
|