So one of the things relayd's snmp agentx hook provieds is the relay
sessions. To do that every connection accepted by relayd does 2 IMSG and
the pfe is using linear lists to track them. Because of this the PFE
engine is using more CPU time than needed.
Is anyone using the fast changing session data in snmp? Else I propose to
remove the code.
--
:wq Claudio
? obj
Index: pfe.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/pfe.c,v
retrieving revision 1.89
diff -u -p -r1.89 pfe.c
--- pfe.c 28 May 2017 10:39:15 -0000 1.89
+++ pfe.c 28 Nov 2017 18:45:31 -0000
@@ -252,9 +252,8 @@ pfe_dispatch_relay(int fd, struct privse
struct ctl_stats crs;
struct relay *rlay;
struct ctl_conn *c;
- struct rsession con, *s, *t;
+ struct rsession con;
int cid;
- objid_t sid;
switch (imsg->hdr.type) {
case IMSG_NATLOOK:
@@ -305,38 +304,6 @@ pfe_dispatch_relay(int fd, struct privse
/* Last ack for a previous request */
imsg_compose_event(&c->iev, IMSG_CTL_END,
0, 0, -1, NULL, 0);
- }
- break;
- case IMSG_SESS_PUBLISH:
- IMSG_SIZE_CHECK(imsg, s);
- if ((s = calloc(1, sizeof(*s))) == NULL)
- return (0); /* XXX */
- memcpy(s, imsg->data, sizeof(*s));
- TAILQ_FOREACH(t, &env->sc_sessions, se_entry) {
- /* duplicate registration */
- if (t->se_id == s->se_id) {
- free(s);
- return (0);
- }
- if (t->se_id > s->se_id)
- break;
- }
- if (t)
- TAILQ_INSERT_BEFORE(t, s, se_entry);
- else
- TAILQ_INSERT_TAIL(&env->sc_sessions, s, se_entry);
- break;
- case IMSG_SESS_UNPUBLISH:
- IMSG_SIZE_CHECK(imsg, &sid);
- memcpy(&sid, imsg->data, sizeof(sid));
- TAILQ_FOREACH(s, &env->sc_sessions, se_entry)
- if (s->se_id == sid)
- break;
- if (s) {
- TAILQ_REMOVE(&env->sc_sessions, s, se_entry);
- free(s);
- } else {
- DPRINTF("removal of unpublished session %i", sid);
}
break;
default:
Index: relay.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
retrieving revision 1.236
diff -u -p -r1.236 relay.c
--- relay.c 28 Nov 2017 01:51:47 -0000 1.236
+++ relay.c 28 Nov 2017 18:45:32 -0000
@@ -328,19 +328,6 @@ relay_init(struct privsep *ps, struct pr
}
void
-relay_session_publish(struct rsession *s)
-{
- proc_compose(env->sc_ps, PROC_PFE, IMSG_SESS_PUBLISH, s, sizeof(*s));
-}
-
-void
-relay_session_unpublish(struct rsession *s)
-{
- proc_compose(env->sc_ps, PROC_PFE, IMSG_SESS_UNPUBLISH,
- &s->se_id, sizeof(s->se_id));
-}
-
-void
relay_statistics(int fd, short events, void *arg)
{
struct privsep *ps = arg;
@@ -1120,7 +1107,6 @@ relay_accept(int fd, short event, void *
relay_sessions++;
SPLAY_INSERT(session_tree, &rlay->rl_sessions, con);
- relay_session_publish(con);
/* Increment the per-relay session counter */
rlay->rl_stats[ps->ps_instance].last++;
@@ -1667,7 +1653,6 @@ relay_close(struct rsession *con, const
struct protocol *proto = rlay->rl_proto;
SPLAY_REMOVE(session_tree, &rlay->rl_sessions, con);
- relay_session_unpublish(con);
event_del(&con->se_ev);
if (con->se_in.bev != NULL)
Index: relay_udp.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/relay_udp.c,v
retrieving revision 1.47
diff -u -p -r1.47 relay_udp.c
--- relay_udp.c 4 Jul 2017 19:59:51 -0000 1.47
+++ relay_udp.c 28 Nov 2017 18:45:32 -0000
@@ -275,7 +275,6 @@ relay_udp_server(int fd, short sig, void
relay_sessions++;
SPLAY_INSERT(session_tree, &rlay->rl_sessions, con);
- relay_session_publish(con);
/* Increment the per-relay session counter */
rlay->rl_stats[ps->ps_instance].last++;
Index: relayd.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/relayd.c,v
retrieving revision 1.170
diff -u -p -r1.170 relayd.c
--- relayd.c 27 Nov 2017 21:06:26 -0000 1.170
+++ relayd.c 28 Nov 2017 18:45:33 -0000
@@ -182,7 +182,6 @@ main(int argc, char *argv[])
env->sc_conffile = conffile;
env->sc_conf.opts = opts;
TAILQ_INIT(&env->sc_hosts);
- TAILQ_INIT(&env->sc_sessions);
env->sc_rtable = getrtable();
/* initialize the TLS session id to a random key for all relay procs */
arc4random_buf(env->sc_conf.tls_sid, sizeof(env->sc_conf.tls_sid));
Index: relayd.h
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/relayd.h,v
retrieving revision 1.248
diff -u -p -r1.248 relayd.h
--- relayd.h 28 Nov 2017 18:25:53 -0000 1.248
+++ relayd.h 28 Nov 2017 18:45:33 -0000
@@ -971,8 +971,6 @@ enum imsg_type {
IMSG_CFG_DONE,
IMSG_CA_PRIVENC,
IMSG_CA_PRIVDEC,
- IMSG_SESS_PUBLISH, /* from relay to pfe */
- IMSG_SESS_UNPUBLISH,
IMSG_TLSTICKET_REKEY
};
@@ -1080,7 +1078,6 @@ struct relayd {
struct routerlist *sc_rts;
struct netroutelist *sc_routes;
struct ca_pkeylist *sc_pkeys;
- struct sessionlist sc_sessions;
char sc_demote_group[IFNAMSIZ];
u_int16_t sc_id;
int sc_rtable;
@@ -1209,8 +1206,6 @@ void relay_match(struct kvlist *, struc
struct kvtree *);
void relay_session_insert(struct rsession *);
void relay_session_remove(struct rsession *);
-void relay_session_publish(struct rsession *);
-void relay_session_unpublish(struct rsession *);
SPLAY_PROTOTYPE(session_tree, rsession, se_nodes, relay_session_cmp);
Index: snmp.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/snmp.c,v
retrieving revision 1.29
diff -u -p -r1.29 snmp.c
--- snmp.c 28 May 2017 10:39:15 -0000 1.29
+++ snmp.c 28 Nov 2017 18:45:33 -0000
@@ -88,8 +88,6 @@ struct router *
snmp_router_byidx(struct relayd *, u_int *, u_int *, u_int, u_int);
struct relay *
snmp_relay_byidx(struct relayd *, u_int *, u_int *, u_int, u_int);
-struct rsession *
- snmp_session_byidx(struct relayd *, u_int *, u_int *, u_int, u_int);
struct rdr *
snmp_rdr_byidx(struct relayd *, u_int *, u_int *, u_int, u_int);
struct netroute *
@@ -105,8 +103,6 @@ int snmp_netroute(struct relayd *, stru
int, uint32_t, uint32_t, u_int);
int snmp_host(struct relayd *, struct snmp_oid *, struct agentx_pdu *,
int, uint32_t, uint32_t, u_int);
-int snmp_session(struct relayd *, struct snmp_oid *, struct agentx_pdu *,
- int, uint32_t, uint32_t, u_int);
int snmp_table(struct relayd *, struct snmp_oid *, struct agentx_pdu *,
int, uint32_t, uint32_t, u_int);
@@ -437,21 +433,6 @@ snmp_agentx_process(struct agentx_handle
oid.o_id[OIDIDX_relaydInfo + 1] = 0;
oid.o_id[OIDIDX_relaydInfo + 2] = 0;
/* FALLTHROUGH */
- case 6:
- log_warnx("%s: sessions", __func__);
- if (infoendidx < 6)
- break;
- if (snmp_session(env, &oid, resp, getnext,
- infoentryendidx, infoentryidxendidx,
- sr.include) == 0)
- break;
- if (!getnext)
- goto nosuchinstance;
-
- oid.o_id[OIDIDX_relaydInfo] = 7;
- oid.o_id[OIDIDX_relaydInfo + 1] = 0;
- oid.o_id[OIDIDX_relaydInfo + 2] = 0;
- /* FALLTHROUGH */
case 7:
log_warnx("%s: tables", __func__);
if (infoendidx < 7)
@@ -1016,56 +997,6 @@ snmp_host_byidx(struct relayd *env, u_in
return (NULL);
}
-struct rsession *
-snmp_session_byidx(struct relayd *env, u_int *instanceidx, u_int *objectidx,
- u_int getnext, u_int include)
-{
- struct rsession *session;
-
- if (*objectidx > SESSION_MAX_SUBIDX)
- return (NULL);
- if (*objectidx == 0) {
- if (!getnext)
- return (NULL);
- *objectidx = 1;
- }
-
- restart:
- TAILQ_FOREACH(session, &env->sc_sessions, se_entry) {
- if (session->se_id >= *instanceidx) {
- if (getnext) {
- /* Lexographical ordering */
-
- /* 1) try the next instance index */
- if (session->se_id == *instanceidx && !include)
- session = TAILQ_NEXT(session, se_entry);
- if (session) {
- *instanceidx = session->se_id;
- return (session);
- }
-
- /* 2) try the next object index */
- if (*objectidx < SESSION_MAX_SUBIDX) {
- *objectidx += 1;
- *instanceidx = 1;
- include = 1;
- goto restart;
- }
-
- /* 3) no further OIDs under this prefix */
- return (NULL);
- }
-
- if (session->se_id == *instanceidx)
- return (session);
-
- return (NULL);
- }
- }
-
- return (NULL);
-}
-
struct table *
snmp_table_byidx(struct relayd *env, u_int *instanceidx, u_int *objectidx,
u_int getnext, u_int include)
@@ -1554,132 +1485,6 @@ snmp_host(struct relayd *env, struct snm
break;
default:
fatalx("unhandled host element id");
- }
-
- return (0);
-}
-
-int
-snmp_session(struct relayd *env, struct snmp_oid *oid, struct agentx_pdu *resp,
- int getnext, uint32_t einstanceidx, uint32_t eobjectidx, u_int include)
-{
- struct timeval tv, now;
- time_t ticks;
- struct rsession *session;
- u_int instanceidx, objectidx;
- u_int32_t status, pid, port, addrtype;
-
- instanceidx = oid->o_id[OIDIDX_relaydInfo + 2];
- objectidx = oid->o_id[OIDIDX_relaydInfo + 1];
- session = snmp_session_byidx(env, &instanceidx, &objectidx, getnext,
- include);
- if (session == NULL)
- return (-1);
-
- if (instanceidx >= einstanceidx || objectidx >= eobjectidx)
- return (0);
-
- oid->o_id[OIDIDX_relaydInfo + 1] = objectidx;
- oid->o_id[OIDIDX_relaydInfo + 2] = instanceidx;
-
- switch (objectidx) {
- case 1: /* index */
- if (snmp_agentx_varbind(resp, oid,
- AGENTX_INTEGER, &session->se_id,
- sizeof(session->se_id)) == -1)
- return (-1);
- break;
- case 2: /* relay index */
- if (snmp_agentx_varbind(resp, oid,
- AGENTX_INTEGER, &session->se_relayid,
- sizeof(session->se_relayid)) == -1)
- return (-1);
- break;
- case 3: /* in address */
- if (snmp_agentx_varbind(resp, oid,
- AGENTX_OCTET_STRING, sstodata(&session->se_in.ss),
- sstolen(&session->se_in.ss)) == -1)
- return (-1);
- break;
- case 4: /* in address type */
- if (session->se_in.ss.ss_family == AF_INET)
- addrtype = 1;
- else if (session->se_in.ss.ss_family == AF_INET6)
- addrtype = 2;
- if (snmp_agentx_varbind(resp, oid,
- AGENTX_INTEGER, &addrtype,
- sizeof(addrtype)) == -1)
- return (-1);
- break;
- case 5: /* out address */
- if (snmp_agentx_varbind(resp, oid,
- AGENTX_OCTET_STRING, sstodata(&session->se_out.ss),
- sstolen(&session->se_out.ss)) == -1)
- return (-1);
- break;
- case 6: /* out address type */
- if (session->se_out.ss.ss_family == AF_INET)
- addrtype = 1;
- else if (session->se_out.ss.ss_family == AF_INET6)
- addrtype = 2;
- if (snmp_agentx_varbind(resp, oid,
- AGENTX_INTEGER, &addrtype,
- sizeof(addrtype)) == -1)
- return (-1);
- break;
- case 7: /* port out */
- port = session->se_out.port;
- if (snmp_agentx_varbind(resp, oid,
- AGENTX_INTEGER, &port,
- sizeof(port)) == -1)
- return (-1);
- break;
- case 8: /* port in */
- port = session->se_in.port;
- if (snmp_agentx_varbind(resp, oid,
- AGENTX_INTEGER, &port,
- sizeof(port)) == -1)
- return (-1);
- break;
- case 9: /* age */
- getmonotime(&now);
- timerclear(&tv);
- timersub(&now, &session->se_tv_start, &tv);
- ticks = tv.tv_sec * 100 + tv.tv_usec / 10000;
- if (snmp_agentx_varbind(resp, oid,
- AGENTX_INTEGER, &ticks,
- sizeof(ticks)) == -1)
- return (-1);
- break;
- case 10: /* idle time */
- getmonotime(&now);
- timerclear(&tv);
- timersub(&now, &session->se_tv_last, &tv);
- ticks = tv.tv_sec * 100 + tv.tv_usec / 10000;
- if (snmp_agentx_varbind(resp, oid,
- AGENTX_INTEGER, &ticks,
- sizeof(ticks)) == -1)
- return (-1);
- break;
- case 11: /* status */
- if (session->se_done)
- status = 1;
- else
- status = 0;
- if (snmp_agentx_varbind(resp, oid,
- AGENTX_INTEGER, &status,
- sizeof(status)) == -1)
- return (-1);
- break;
- case 12: /* session pid */
- pid = (u_int32_t)session->se_pid;
- if (snmp_agentx_varbind(resp, oid,
- AGENTX_INTEGER, &pid,
- sizeof(pid)) == -1)
- return (-1);
- break;
- default:
- fatalx("unhandled table element id");
}
return (0);