2 // Copyright (c) 2010-2017 Intel Corporation
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
17 #ifndef _GENL4_STREAM_H_
18 #define _GENL4_STREAM_H_
20 #include "prox_lua_types.h"
21 #include "pkt_parser.h"
22 #include "token_time.h"
37 static const char *tcp_state_to_str(const enum tcp_state s)
47 return "SYN_RECEIVED";
59 return "INVALID_STATE";
63 #define STREAM_CTX_F_EXPIRED 0x01
64 #define STREAM_CTX_F_NEW_DATA 0x02 /* Set on recv to track first ACK of data */
65 #define STREAM_CTX_F_TCP_ENDED 0x04
66 #define STREAM_CTX_F_TCP_GOT_SYN 0x08 /* Set only once when syn has been received */
67 #define STREAM_CTX_F_TCP_GOT_FIN 0x10 /* Set only once when fin has been received */
68 #define STREAM_CTX_F_MORE_DATA 0x20
69 #define STREAM_CTX_F_LAST_RX_PKT_MADE_PROGRESS 0x40
71 /* Run-time structure to management state information associated with current stream_cfg. */
76 enum tcp_state tcp_state;
77 struct token_time token_time;
78 struct token_time token_time_other;
84 uint32_t ackable_data_seq;
85 uint32_t seq_first_byte; /* seq number - seq_first_byte gives offset within content. */
86 uint32_t other_seq_first_byte; /* seq number - seq_first_byte gives offset within content. */
90 const struct stream_cfg *stream_cfg; /* Current active steam_cfg */
91 struct pkt_tuple *tuple;
102 struct peer_data data[2];
103 struct host_set servers; // Current implementation only allows mask == 0. (i.e. single server)
104 struct token_time_cfg tt_cfg[2]; // bytes per period rate
106 uint64_t tsc_timeout;
107 uint64_t tsc_timeout_time_wait;
111 int (*proc)(struct stream_ctx *meta, struct rte_mbuf *mbuf, struct l4_meta *l4_meta, uint64_t *next_tsc);
112 int (*is_ended)(struct stream_ctx *meta);
113 struct peer_action actions[0];
116 static void scale_for_jitter(uint64_t *to_scale)
121 static void reset_token_times(struct stream_ctx *ctx)
123 const uint64_t now = rte_rdtsc();
124 const struct stream_cfg *cfg = ctx->stream_cfg;
125 enum l4gen_peer peer = ctx->peer;
127 token_time_init(&ctx->token_time, &cfg->tt_cfg[peer]);
128 token_time_reset_full(&ctx->token_time, now);
130 token_time_init(&ctx->token_time_other, &cfg->tt_cfg[!peer]);
131 scale_for_jitter(&ctx->token_time_other.cfg.bytes_max);
132 token_time_reset_full(&ctx->token_time_other, now);
135 static void stream_ctx_init(struct stream_ctx *ctx, enum l4gen_peer peer, struct stream_cfg *cfg, struct pkt_tuple *tuple)
137 ctx->stream_cfg = cfg;
141 /* Server's initial state is different from client for
142 TCP. For now, don't use a specific init function for
143 TCP/UDP since there is not a lot of difference and to avoid
144 an additional function pointer. */
145 ctx->tcp_state = PEER_CLIENT == peer? CLOSED : LISTEN;
146 ctx->other_mss = 536; /* default 536 as per RFC 879 */
148 reset_token_times(ctx);
151 static void stream_ctx_reset_move(struct stream_ctx *ctx, struct stream_cfg *cfg)
153 enum l4gen_peer peer = ctx->peer;
154 struct pkt_tuple *tuple = ctx->tuple;
156 memset(ctx, 0, sizeof(*ctx));
157 stream_ctx_init(ctx, peer, cfg, tuple);
160 static int stream_cfg_calc_max_payload_len(struct stream_cfg *cfg, enum l4gen_peer peer)
162 const uint32_t l4_hdr_len = cfg->proto == IPPROTO_UDP?
163 sizeof(prox_rte_udp_hdr) : sizeof(prox_rte_tcp_hdr);
165 return PROX_RTE_ETHER_MAX_LEN - PROX_RTE_ETHER_CRC_LEN - cfg->data[peer].hdr_len - l4_hdr_len;
168 static int stream_cfg_max_n_segments(struct stream_cfg *cfg)
170 if (cfg->proto == IPPROTO_UDP)
176 const uint32_t mss = stream_cfg_calc_max_payload_len(cfg, PEER_CLIENT);
178 for (uint32_t i = 0; i < cfg->n_actions; ++i) {
179 cur = (cfg->actions[i].len + (mss - 1)) / mss;
180 ret = ret > cur? ret: cur;
186 static int stream_cfg_verify_action(struct stream_cfg *cfg, struct peer_action *action)
188 if (cfg->proto == IPPROTO_TCP)
191 uint16_t max_payload_len = stream_cfg_calc_max_payload_len(cfg, action->peer);
193 PROX_PANIC(action->len > max_payload_len,
194 "Action %zu has length %u while for the maximum action length for UDP connections is limited to %u\n",
195 action - cfg->actions,
201 #endif /* _GENL4_STREAM_H_ */