Statman and ICMP#1222
Conversation
…d and working on other ICMP messages
…eation of Stat throws Exception, empty name-input to get-method now throws immediate Exception
…(RFC 1122). Removed deprecated ICMP messages (Source Quench and Information - RFC 6918 and 6633)
…nstead of previously updated statman_.end() iterator
…so that UDP and IP4 have access to them
…ed message, port and protocol unreachable validated in test.py
…nding to incoming ping requests
… span. Get(name) method using last_used-iterator instead of end
… on linux for now)
…moving them on timeout), updating integration test correspondingly and setting timeout to 40 (reply) and 50 (test)
|
Jenkins test please |
… exceeded messages implemented
…need for IP forwarding)
…heck on transmitted packets as well
…ng error CPU model host requires KVM
…with dns set to 10.0.0.1 changed to 8.8.8.8
… ICMP_packet and small cleanups
…ot broadcast or multicast (RFC 1122)
|
Jenkins test please |
AndreasAakesson
left a comment
There was a problem hiding this comment.
Looking good 👍 Just some minor stuff/improvements
| * Error report in accordance with RFC 1122 | ||
| * An ICMP error message has been received - forward to transport layer (UDP or TCP) | ||
| */ | ||
| void error_report(Error_type type, Error_code code, Span icmp_payload) override { |
There was a problem hiding this comment.
Can this be put in .cpp?
| ICMP_callback(ICMPv4& icmp, Tuple t, icmp_func cb) | ||
| : tuple{t}, callback{cb} | ||
| { | ||
| timer_id = Timers::oneshot(std::chrono::seconds(40), [&icmp, t](Timers::id_t) { |
There was a problem hiding this comment.
Maybe have the timeout duration configurable (like passed into the origin call that creates a ICMP callback)?
Or at least define the timeout duration static outside the callback struct, and have it globally configurable.
There was a problem hiding this comment.
Would make sense as part of ping(...)
| auto it = ping_callbacks_.find(std::make_pair(ping_response.id(), ping_response.sequence())); | ||
|
|
||
| if (it != ping_callbacks_.end()) { | ||
| it->second.callback(ICMP_packet{ping_response.id(), ping_response.sequence(), ping_response.ip().ip_src(), |
There was a problem hiding this comment.
To make it cleaner you could add a constructor to struct ICMP_packet that takes a const icmp4::Packet& and hide all these lines there (with a shorter name).
| } // < namespace code | ||
|
|
||
| static std::string __attribute__((unused)) get_type_string(Type type) { | ||
| return [&type] () { |
There was a problem hiding this comment.
This lambda doesn't fill any purpose here.
| } | ||
|
|
||
| static std::string __attribute__((unused)) get_code_string(Type type, uint8_t code) { | ||
| return [&type, &code] () { |
There was a problem hiding this comment.
Same as above.
Maybe have helper functions for the nested switch cases? It also could make sense to move this to a cpp file.
| } | ||
|
|
||
| void ICMPv4::destination_unreachable(Packet_ptr pckt, icmp4::code::Dest_unreachable code) { | ||
| if ((size_t)pckt->size() < sizeof(IP4::header) + icmp4::Packet::header_size()) // Drop if not a full header |
There was a problem hiding this comment.
You could make it more DRY by creating a inline helper function for this, and also use UNLIKELY:
if(UNLIKELY(not full_header(*pckt))) return;
(Could this be done before any of the functions are called?)
|
|
||
| void ICMPv4::forward_to_transport_layer(icmp4::Packet& req) { | ||
| // inet forwards to transport layer (UDP or TCP) | ||
| inet_.error_report(req.type(), req.code(), req.payload()); |
There was a problem hiding this comment.
I suggest passing the underlying packet as IP packet pointer to retain storage of the underlying buffer. e.g.
auto packet_ptr = req.release();
packet_ptr -> set_layer_begin(req.payload()); // hide information below payload, interpret the rest as Packet_IP4
inet_.error_report(type, code, std::move(packet_ptr));
| { | ||
| stack_.icmp().destination_unreachable(std::move(packet), icmp4::code::Dest_unreachable::PROTOCOL); | ||
| } | ||
|
|
| TRAILER_NEGO = 0x0010, // RFC 893 Trailer negotiation | ||
| TRAILER_FIRST = 0x0110, // RFC 893, 1122 Trailer encapsulation | ||
| TRAILER_LAST = 0x0f10 | ||
| }; |
| operator bool() const noexcept | ||
| { return type_ != icmp4::Type::NO_REPLY; } | ||
|
|
||
| std::string to_string(); |
| ICMP_callback(ICMPv4& icmp, Tuple t, icmp_func cb) | ||
| : tuple{t}, callback{cb} | ||
| { | ||
| timer_id = Timers::oneshot(std::chrono::seconds(40), [&icmp, t](Timers::id_t) { |
There was a problem hiding this comment.
Would make sense as part of ping(...)
| netmask_{stack_.netmask()}, | ||
| router_{stack_.gateway()}, | ||
| dns_{stack_.gateway()}, | ||
| dns_{stack_.dns()}, |
There was a problem hiding this comment.
If there's a getter for both the DNS client and the DNS address, this is ambiguous
There was a problem hiding this comment.
For IP I think we used ip_obj and ip_addr
| (t >= net::ntohs(static_cast<uint16_t>(Ethertype::TRAILER_FIRST)) and | ||
| t <= net::ntohs(static_cast<uint16_t>(Ethertype::TRAILER_LAST))))) { | ||
| debug("<Ethernet OUT> Ethernet type Trailer is not supported. Packet is not transmitted\n"); | ||
| return; |
There was a problem hiding this comment.
👍 (we might want to add TX_dropped as either delegate or just stat - but we can do that later)
| } | ||
| } | ||
|
|
||
| void UDP::error_report(Error_type type, Error_code code, |
There was a problem hiding this comment.
Signature will change to e.g. UDP::error_report(ICMP_Error) or something, as discussed
| return ss.str(); | ||
| } | ||
|
|
||
| void TCP::error_report(Error_type type, Error_code code, |
There was a problem hiding this comment.
New signature as discussed for UDP
| }); | ||
|
|
||
| // Also possible without callback: | ||
| // inet.icmp().ping(IP4::addr{193,90,147,109}); // google.com |
There was a problem hiding this comment.
Would also be nice to do DNS resolution - so you could ping("google.com", callback). For later.
…ad of Span (move away from raw pointers)
Updates based on feedback on #1222 and more
No description provided.