Flow 1.0.0
Flow project: Full implementation reference.
net_flow_fwd.hpp
Go to the documentation of this file.
1/* Flow
2 * Copyright 2023 Akamai Technologies, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the
5 * "License"); you may not use this file except in
6 * compliance with the License. You may obtain a copy
7 * of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in
12 * writing, software distributed under the License is
13 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
14 * CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing
16 * permissions and limitations under the License. */
17
18/// @file
19#pragma once
20
21#include "flow/common.hpp"
22#include <ostream>
23
24namespace flow::net_flow
25{
26// Types.
27
28// Find doc headers near the bodies of these compound types.
29
30struct Ack_packet;
31class Congestion_control_classic;
32class Congestion_control_classic_data;
33class Congestion_control_classic_with_bandwidth_est;
34class Congestion_control_strategy;
35class Congestion_control_selector;
36struct Data_packet;
37class Drop_timer;
38struct Low_lvl_packet;
39class Peer_socket_receive_stats_accumulator;
40class Peer_socket_send_stats_accumulator;
41class Port_space;
42struct Rst_packet;
43class Send_bandwidth_estimator;
44struct Send_pacing_data;
45class Sequence_number;
46class Socket_buffer;
47struct Syn_packet;
48struct Syn_ack_packet;
49struct Syn_ack_ack_packet;
50
51// Free functions.
52
53/**
54 * Applies the given `ostream` manipulator function to the given `ostream` -- just like standard streams already
55 * allow, but with the function given as a flow::Function object instead of a raw function pointer.
56 * Without this, the flow::Function is usually converted to a `bool` or something and just printed out as
57 * `"1"` -- which is not useful.
58 *
59 * Much like with standard function manipulators (`std::endl`, for example), the idea is for this to work:
60 *
61 * ~~~
62 * cout << print_something_to_ostream << ":" << xyz;
63 * // ...
64 * // But in this case, print_something_to_stream is of type: Function<ostream& (ostream&)>.
65 * // E.g., ahead of the `cout` this could have been done, assuming: ostream& func(ostream& os, bool some_flag):
66 * flow::Function<ostream& (ostream&)> print_something_to_stream
67 * = [](ostream& os) -> ostream& { return func(os, false); };
68 * // Or with a non-static class member function: class Some_class { ostream& func(ostream& os, bool some_flag); }.
69 * Some_class some_instance;
70 * flow::Function<ostream& (ostream&)> print_something_to_stream
71 * = [some_instance](ostream& os) -> ostream& { return some_instance->func(os, false); };
72 * ~~~
73 *
74 * @warning It is important for this to be in namespace `flow::net_flow`, not higher (such as `flow`) or lower.
75 * Otherwise the places needing this overload to be used won't, and it will either not compile;
76 * or compile but invoke some other, useless overload. Unfortunately placing it into a containing
77 * namespace makes it not work from within a contained namespace.
78 *
79 * @note You may note the above technique is not used for argument-bearing `std` stream manipulators; for example
80 * `std::setw()`. The technique used to make that work is that `setw()` would return some internal `struct`
81 * (of unknown-to-user type `T`), in which it has stored the argument to `setw()`; and an `operator<<(ostream, T)`
82 * overload is defined; this overload would actually set the field width (or
83 * whatever `setw()` is supposed to do) on the `ostream` -- using the arg value
84 * stored in the `T`. That works, and it may be somewhat more performant than our solution; but our solution
85 * is *much* more elegant and concise; it lets one build stream manipulators out of any function at all,
86 * the only requirements on it being that it returns an `ostream&` and takes same as *an* argument.
87 * The `std` technique allows the same, but we can do it with a single and expressive `bind()` call instead of
88 * a hidden internal `struct type`, explicitly storing arguments, documenting that stuff, etc.
89 * (We can change individual cases to use the `std`-style solution, if performance needs call for it, but so far
90 * there has been no such needs.) To be fair, the `std` solution is ALSO easier/more expressive at the
91 * actual call site. That is, in the above examples, one could just do: `cout << func(false) << ":" << xyz;` or
92 * `cout << some_instance.func(false) << ":" << xyz;`, respectively. That's easier to read than the `bind()`
93 * constructs above; but the code elsewhere that makes those `func()`s work is a huge mess that our solution
94 * completely avoids. For us, all that is needed behind the scenes is the present `operator<<` overload.
95 *
96 * @param os
97 * Stream to write to/mutate.
98 * @param os_manip
99 * A flow::Function object that points to a manipulator, which is a function that takes a mutable
100 * `ostream`, writes something to it and/or acts on it in some other non-`const` way; and returns the original
101 * reference to mutable `ostream`.
102 * @return `os`.
103 */
104std::ostream& operator<<(std::ostream& os, const Function<std::ostream& (std::ostream&)>& os_manip);
105
106/**
107 * Prints a printable representation of the data in `sock_buf` to the given standard `ostream`. Exactly
108 * one line per block is used. This implementation is slow; use only in DATA logging, or where
109 * performance does not matter.
110 *
111 * @param os
112 * Stream to which to write.
113 * @param sock_buf
114 * Object to serialize.
115 * @return `os`.
116 */
117std::ostream& operator<<(std::ostream& os, const Socket_buffer& sock_buf);
118
119/**
120 * Prints given sequence number to given `ostream`.
121 *
122 * set_metadata()'s effects are felt here; see Sequence_number class doc header for details.
123 *
124 * @param os
125 * Stream to which to print.
126 * @param seq_num
127 * Object to serialize.
128 * @return `os`.
129 */
130std::ostream& operator<<(std::ostream& os, const Sequence_number& seq_num);
131
132/**
133 * Free function that returns `seq_num.hash()`; has to be a free function named `hash_value`
134 * for boost.hash to pick it up.
135 *
136 * @relatesalso Sequence_number
137 *
138 * @param seq_num
139 * Object to hash.
140 * @return `seq_num.hash()`.
141 */
142size_t hash_value(const Sequence_number& seq_num);
143
144} // namespace flow::net_flow
Flow module containing the API and implementation of the Flow network protocol, a TCP-inspired stream...
Definition: node.cpp:25
size_t hash_value(const Sequence_number &seq_num)
Free function that returns seq_num.hash(); has to be a free function named hash_value for boost....
Definition: seq_num.cpp:275
std::ostream & operator<<(std::ostream &os, const Congestion_control_selector::Strategy_choice &strategy_choice)
Serializes a Peer_socket_options::Congestion_control_strategy_choice enum to a standard ostream – the...
Definition: cong_ctl.cpp:146