jcs
/subtext
/amendments
/173
telnet: Pre-allocate nodes, bump max to 10
This way we aren't constantly trying to find space for these big
chunks of memory for every new connection.
jcs made amendment 173 over 2 years ago
--- telnet.c Thu Jun 23 10:05:22 2022
+++ telnet.c Thu Jun 23 14:21:30 2022
@@ -109,7 +109,7 @@ struct telnet_node {
rdsEntry tcp_rds[2];
};
-#define MAX_TELNET_NODES 5
+#define MAX_TELNET_NODES 10
static struct telnet_node *telnet_nodes[MAX_TELNET_NODES] = { NULL };
static struct telnet_node *telnet_listener_node = NULL;
static TCPiopb telnet_exit_pb;
@@ -135,7 +135,7 @@ static const char * vt100_terms[] = {
};
void telnet_setup(struct session *session);
-void telnet_create_listener_node(short node_idx);
+void telnet_listen_on_node(struct telnet_node *node);
void telnet_output_iac(struct session *session, const char *iacs,
size_t len);
bool telnet_ip_is_banned(ip_addr ip);
@@ -150,6 +150,8 @@ struct node_funcs telnet_node_funcs = {
void
telnet_init(void)
{
+ short n;
+
if (!db->config.telnet_port)
return;
@@ -157,6 +159,15 @@ telnet_init(void)
if (_TCPInit() != noErr)
panic("Failed initializing MacTCP");
+
+ /* pre-allocate nodes */
+ for (n = 0; n < MAX_TELNET_NODES; n++) {
+ telnet_nodes[n] = xmalloczero(sizeof(struct telnet_node));
+ telnet_nodes[n]->id = n;
+
+ if (n == 0)
+ telnet_listen_on_node(telnet_nodes[n]);
+ }
}
void
@@ -181,18 +192,19 @@ telnet_atexit(void)
}
void
-telnet_create_listener_node(short node_idx)
+telnet_listen_on_node(struct telnet_node *node)
{
char ip_s[20];
- struct telnet_node *node;
- short error;
+ short error, id;
ip_addr ip;
tcp_port port;
long mask;
- node = xmalloczero(sizeof(struct telnet_node));
- node->id = node_idx;
- snprintf(node->name, sizeof(node->name), "ttyt%d", node_idx);
+ id = node->id;
+ memset(node, 0, sizeof(struct telnet_node));
+ node->id = id;
+
+ snprintf(node->name, sizeof(node->name), "ttyt%d", id);
error = _TCPCreate(&node->listen_pb, &node->stream,
(Ptr)&node->tcp_buf, sizeof(node->tcp_buf), nil, nil, nil, false);
@@ -218,7 +230,6 @@ telnet_create_listener_node(short node_idx)
node->id, db->config.telnet_port, error);
node->state = TELNET_PB_STATE_LISTENING;
- telnet_nodes[node->id] = node;
telnet_listener_node = node;
}
@@ -234,14 +245,11 @@ telnet_idle(void)
for (n = 0; n < MAX_TELNET_NODES; n++) {
node = telnet_nodes[n];
- if (!node) {
- if (telnet_listener_node != NULL)
- continue;
- telnet_create_listener_node(n);
- continue;
- }
-
switch (node->state) {
+ case TELNET_PB_STATE_UNUSED:
+ if (telnet_listener_node == NULL)
+ telnet_listen_on_node(node);
+ break;
case TELNET_PB_STATE_LISTENING:
error = _TCPStatus(&node->send_pb, node->stream,
&telnet_status_pb, nil, nil, false);
@@ -283,8 +291,7 @@ telnet_idle(void)
_TCPRelease(&node->listen_pb, node->stream, nil,
nil, false);
- telnet_nodes[n] = NULL;
- free(node);
+ node->state = TELNET_PB_STATE_UNUSED;
goto next_node;
}
@@ -316,16 +323,15 @@ telnet_idle(void)
else {
_TCPRelease(&node->listen_pb, node->stream, nil, nil,
false);
- telnet_nodes[n] = telnet_listener_node = NULL;
- free(node);
+ node->state = TELNET_PB_STATE_UNUSED;
+ telnet_listener_node = NULL;
}
goto next_node;
}
break;
case TELNET_PB_STATE_CONNECTED:
if (!node->session) {
- free(node);
- telnet_nodes[n] = NULL;
+ node->state = TELNET_PB_STATE_UNUSED;
break;
}
@@ -803,8 +809,7 @@ telnet_close(struct session *session)
}
session->cookie = NULL;
- telnet_nodes[node->id] = NULL;
- free(node);
+ node->state = TELNET_PB_STATE_UNUSED;
}
bool
@@ -815,10 +820,10 @@ telnet_ip_is_banned(ip_addr ip)
bool ret = false;
for (j = 0; j < MAX_BANNED_IPS; j++) {
- if (banned_ips[j].ip &&
+ if (banned_ips[j].ip && Time > banned_ips[j].time &&
(Time - banned_ips[j].time > IP_BAN_SECONDS)) {
long2ip(banned_ips[j].ip, ip_s);
- logger_printf(logger, "[%s] Unbanning IP after %d seconds",
+ logger_printf(logger, "[%s] Unbanning IP after %ld seconds",
ip_s, Time - banned_ips[j].time);
banned_ips[j].ip = 0;
continue;