]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Flock: telnet request sends the request
authorMaria Matejka <mq@ucw.cz>
Tue, 10 Sep 2024 18:43:55 +0000 (20:43 +0200)
committerMaria Matejka <mq@ucw.cz>
Sun, 23 Feb 2025 18:07:35 +0000 (19:07 +0100)
flock/ctl.c
flock/flock.h
flock/hypervisor.c

index 1552993b0934e5c914ba2e8f6180de69bbdeec56..e2dc8f51ed9b1c69c69f991c0ae70c36cc38ca7b 100644 (file)
@@ -184,9 +184,12 @@ hcs_parse(struct cbor_parser_context *ctx, const byte *buf, s64 size)
          case 3: /* telnet listener open */
            if ((ctx->type != 7) || (ctx->value != 22))
              CBOR_PARSER_ERROR("Expected null, got %u-%u", ctx->type, ctx->value);
+           /* TODO: allow this also for machines */
 
            log(L_INFO "Requested telnet open");
 
+           hexp_get_telnet(ctx->sock, NULL);
+
            ctx->major_state = 1;
            break;
 
index 8cc334800b334168544d4e854b78a9ac4d138771..076d71410b3faa05373351654887fa56f3335669 100644 (file)
@@ -25,6 +25,8 @@ void hcs_parser_cleanup(struct cbor_parser_context *ctx);
 const char *hcs_error(struct cbor_parser_context *ctx);
 bool hcs_complete(struct cbor_parser_context *ctx);
 
+void hexp_get_telnet(sock *, const char *name);
+
 extern event reboot_event, poweroff_event;
 extern event_list shutdown_event_list;
 
index 217eb5a7cbe7c375edd0d2187af7fdc2bb9d55e5..b826a046cac58c9a5906a084135ce1ace4761d1c 100644 (file)
@@ -1,7 +1,9 @@
 #include "lib/birdlib.h"
 
-#include "lib/resource.h"
+#include "lib/cbor.h"
+#include "lib/hash.h"
 #include "lib/io-loop.h"
+#include "lib/resource.h"
 #include "lib/socket.h"
 
 #include "flock/flock.h"
@@ -149,8 +151,18 @@ hypervisor_exposed_parent_err(sock *sk UNUSED, int e UNUSED)
 static int
 hypervisor_exposed_child_rx(sock *sk, uint size UNUSED)
 {
-  log(L_INFO "HV EC RX");
-  recvmsg(sk->fd, NULL, 0);
+  byte buf[128];
+  struct iovec v = {
+    .iov_base = buf,
+    .iov_len = sizeof buf,
+  };
+  struct msghdr m = {
+    .msg_iov = &v,
+    .msg_iovlen = 1,
+  };
+  int e = recvmsg(sk->fd, &m, 0);
+  log(L_INFO "HV EC RX %d", e);
+
   return 0;
 }
 
@@ -211,3 +223,79 @@ hypervisor_exposed_fork(void)
   /* Wait for Godot */
   birdloop_minimalist_main();
 }
+
+
+/**
+ * Hypervisor's mapping between external ports and names
+ */
+
+#define HEXP_TELNET_KEY(tp)    tp->name, tp->hash
+#define HEXP_TELNET_NEXT(tp)   tp->next
+#define HEXP_TELNET_EQ(a,h,b,i)        ((h) == (i)) && (!(a) && !(b) || !strcmp(a,b))
+#define HEXP_TELNET_FN(a,h)    h
+
+struct hexp_telnet_port {
+  struct hexp_telnet_port *next;
+  const char *name;
+  uint hash;
+  uint port;
+};
+
+static struct hexp_telnet {
+  pool *pool;
+  HASH(struct hexp_telnet_port) port_hash;
+} hexp_telnet;
+
+static void
+hexp_init_telnet(void)
+{
+  pool *p = rp_new(hcs_pool, hcs_pool->domain, "Hypervisor exposed telnets");
+  hexp_telnet.pool = p;
+  HASH_INIT(hexp_telnet.port_hash, p, 6);
+}
+
+static void
+hexp_have_telnet(sock *s, struct hexp_telnet_port *p)
+{
+  struct linpool *lp = lp_new(s->pool);
+  struct cbor_writer *cw = cbor_init(s->tbuf, s->tbsize, lp);
+  cbor_open_block_with_length(cw, 1);
+  cbor_add_int(cw, -2);
+  cbor_add_int(cw, p->port);
+  sk_send(s, cw->pt);
+  rfree(lp);
+}
+
+void
+hexp_get_telnet(sock *s, const char *name)
+{
+  if (!hexp_telnet.pool)
+    hexp_init_telnet();
+
+  uint h = name ? mem_hash(name, strlen(name)) : 0;
+  struct hexp_telnet_port *p = HASH_FIND(hexp_telnet.port_hash, HEXP_TELNET, name, h);
+  if (p)
+    return hexp_have_telnet(s, p);
+
+  uint8_t buf[64];
+  linpool *lp = lp_new(s->pool);
+  struct cbor_writer *cw = cbor_init(buf, sizeof buf, lp);
+  cbor_open_block_with_length(cw, 1);
+  cbor_add_int(cw, 1);
+  cw->cbor[cw->pt++] = 0xf6;
+
+  struct iovec v = {
+    .iov_base = buf,
+    .iov_len = cw->pt,
+  };
+  struct msghdr m = {
+    .msg_iov = &v,
+    .msg_iovlen = 1,
+  };
+
+  int e = sendmsg(he.s->fd, &m, 0);
+  if (e != cw->pt)
+    bug("sendmsg error handling not implemented, got %d (%m)", e);
+
+  rfree(lp);
+}