mirror of
https://github.com/brazilofmux/tinymux
synced 2026-08-13 00:23:11 -04:00
#1800: Keep DS_NEED_PROTO while bytes are a proper prefix of "GET "; buffer and replay into WS or telnet once classified; grace timeout replays any partial preface. #1802: Cap SMTP read reassembly (64 KiB); 120s overall deadline; surface queue/flush failures so the singleton channel cannot wedge forever. #1803: If any listen port was configured but none started, fail initialize() (clean teardown) instead of running a dead network service. #1801 (Win32 adoptConnection for @email) remains open — needs engine initiateConnect on wselect/IOCP.
128 lines
3.6 KiB
C++
128 lines
3.6 KiB
C++
/*! \file interface.h
|
|
* \brief Driver-side struct definitions: DESC and port_info.
|
|
*
|
|
* This header provides the full descriptor_data (DESC) struct definition
|
|
* and port_info. Engine files that only need forward declarations of DESC
|
|
* or program_data, plus telnet/NVT constants, get those from externs.h.
|
|
*
|
|
* Only include this header in files that dereference DESC members or
|
|
* access main_game_ports.
|
|
*/
|
|
|
|
#pragma once
|
|
#include "copyright.h"
|
|
|
|
#ifndef INTERFACE_H
|
|
#define INTERFACE_H
|
|
|
|
struct ws_state;
|
|
|
|
// Telnet subnegotiation accumulator size. Must be large enough to
|
|
// hold the longest subnegotiation payload modern clients send —
|
|
// GMCP JSON, MSDP, TTYPE chains, and CHARSET lists can each exceed
|
|
// the old 64-byte SBUF_SIZE cap. 4096 matches PennMUSH and covers
|
|
// all protocols we currently parse without being wasteful.
|
|
//
|
|
constexpr size_t TELNET_OPTION_SIZE = 4096;
|
|
|
|
// Full descriptor_data struct definition.
|
|
// Engine files use only the forward declaration from externs.h.
|
|
//
|
|
struct descriptor_data
|
|
{
|
|
SocketState ss;
|
|
SOCKET socket;
|
|
|
|
CLinearTimeAbsolute connected_at;
|
|
CLinearTimeAbsolute last_time;
|
|
|
|
int flags;
|
|
int retries_left;
|
|
int command_count;
|
|
int timeout;
|
|
dbref player;
|
|
UTF8 *output_prefix;
|
|
UTF8 *output_suffix;
|
|
size_t output_size;
|
|
size_t output_tot;
|
|
size_t output_lost;
|
|
std::deque<std::string> output_queue;
|
|
size_t input_size;
|
|
size_t input_tot;
|
|
size_t input_lost;
|
|
bool input_throttled; // hysteresis: dropping input past input_limit
|
|
std::deque<std::string> input_queue;
|
|
UTF8 *raw_input_buf;
|
|
UTF8 *raw_input_at;
|
|
size_t nOption;
|
|
unsigned char aOption[TELNET_OPTION_SIZE];
|
|
|
|
// #1131: set when an IAC SB subnegotiation overran aOption and bytes
|
|
// were dropped. The accumulated buffer is then a truncated prefix, so
|
|
// the completed SB must be discarded rather than parsed. Cleared when
|
|
// a new SB begins and when one completes.
|
|
//
|
|
bool sbOverflow;
|
|
|
|
int raw_input_state;
|
|
int raw_codepoint_state;
|
|
size_t raw_codepoint_length;
|
|
static constexpr int NVT_TABLE_SIZE = 256;
|
|
int nvt_him_state[NVT_TABLE_SIZE];
|
|
int nvt_us_state[NVT_TABLE_SIZE];
|
|
UTF8 *ttype;
|
|
int encoding;
|
|
int negotiated_encoding;
|
|
bool charset_request_pending;
|
|
int width;
|
|
int height;
|
|
bool gmcp_enabled;
|
|
int quota;
|
|
struct program_data* program_data;
|
|
ws_state *ws; // WebSocket state (nullptr if telnet)
|
|
int64_t connlog_id; // SQLite connlog row (0 if not logged)
|
|
|
|
// #1800: partial WebSocket "GET " preface across TCP read boundaries.
|
|
// While DS_NEED_PROTO and len < 4 with a matching prefix of "GET ",
|
|
// bytes accumulate here so a split preface is not forced to telnet.
|
|
//
|
|
char proto_detect_buf[4];
|
|
size_t proto_detect_len;
|
|
|
|
mux_sockaddr address;
|
|
|
|
UTF8 addr[51];
|
|
UTF8 username[11];
|
|
UTF8 doing[SIZEOF_DOING_STRING];
|
|
};
|
|
|
|
typedef struct port_info
|
|
{
|
|
bool fMatched{};
|
|
mux_sockaddr msa;
|
|
SOCKET socket{};
|
|
#ifdef UNIX_SSL
|
|
bool fSSL;
|
|
#endif
|
|
} port_info;
|
|
|
|
#ifdef UNIX_SSL
|
|
extern port_info main_game_ports[MAX_LISTEN_PORTS * 2];
|
|
#else
|
|
extern port_info main_game_ports[MAX_LISTEN_PORTS];
|
|
#endif
|
|
extern int num_main_game_ports;
|
|
|
|
// Connection-refusal log damping (see nospam_connect in net.cpp). Refusing a
|
|
// connection still costs a log write, so a connection flood becomes a disk
|
|
// flood unless refusal logging is damped.
|
|
//
|
|
extern bool refusal_log_wanted(const UTF8 *pAddr);
|
|
|
|
// Per-source connection-rate limit (connect/disconnect churn). See net.cpp.
|
|
//
|
|
extern bool connect_rate_exceeded(const MUX_SOCKADDR &sa, int *pWait);
|
|
extern void connect_rate_charge(const MUX_SOCKADDR &sa);
|
|
extern void refusal_log_flush(void);
|
|
|
|
#endif // !INTERFACE_H
|