0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 09:41:54 +00:00

Flock: Telnet connection to hypervisor seems to work well

This commit is contained in:
Maria Matejka 2024-09-10 21:58:46 +02:00
parent b6aca48277
commit 19dae2c622

View File

@ -8,6 +8,7 @@
#include "flock/flock.h"
#include <stdlib.h>
#include <sys/socket.h>
/**
@ -132,17 +133,87 @@ static struct hypervisor_exposed {
/**
* Exposed process' parent side (requestor)
**/
static int
hypervisor_telnet_connected(sock *sk, uint size UNUSED)
{
int fd = accept(sk->fd, NULL, 0);
if (fd < 0)
{
if (errno == EAGAIN)
return 1;
log(L_ERR "failed to accept telnet connection: %m");
return 0;
}
int e = fork();
if (e < 0)
{
log(L_ERR "failed to fork: %m");
return 0;
}
if (e)
{
log(L_INFO "telnet connected");
close(fd);
return 1;
}
close(0);
close(1);
close(2);
dup2(fd, 0);
dup2(fd, 1);
e = execl("/usr/sbin/telnetd", "telnetd", "-E", "/bin/bash", NULL);
log(L_ERR "failed to execl: %m");
exit(42);
}
static int
hypervisor_exposed_parent_rx(sock *sk, uint size UNUSED)
{
log(L_INFO "HV EP RX");
recvmsg(sk->fd, NULL, 0);
int sfd = -1;
byte buf[128], cbuf[CMSG_SPACE(sizeof sfd)];
struct iovec v = {
.iov_base = buf,
.iov_len = sizeof buf,
};
struct msghdr m = {
.msg_iov = &v,
.msg_iovlen = 1,
.msg_control = &cbuf,
.msg_controllen = sizeof cbuf,
};
int e = recvmsg(sk->fd, &m, 0);
struct cmsghdr *c = CMSG_FIRSTHDR(&m);
memcpy(&sfd, CMSG_DATA(c), sizeof sfd);
ASSERT_DIE(buf[0] == 0xa1);
ASSERT_DIE(buf[1] == 0x21);
ASSERT_DIE(buf[2] == 0x19);
u16 port = ntohs(*((u16 *) &buf[3]));
log(L_INFO "RX %d bytes, fd %d, port %u", e, sfd, port);
sock *skl = sk_new(sk->pool);
skl->type = SK_MAGIC;
skl->rx_hook = hypervisor_telnet_connected;
skl->fd = sfd;
if (sk_open(skl, sk->loop) < 0)
bug("Telnet listener: sk_open failed");
// hexp_received_telnet(port, sfd);
return 0;
}
static void
hypervisor_exposed_parent_err(sock *sk UNUSED, int e UNUSED)
hypervisor_exposed_parent_err(sock *sk, int e UNUSED)
{
sk_close(sk);
}
/**
@ -161,9 +232,88 @@ hypervisor_exposed_child_rx(sock *sk, uint size UNUSED)
.msg_iovlen = 1,
};
int e = recvmsg(sk->fd, &m, 0);
log(L_INFO "HV EC RX %d", e);
if (e != 3)
{
log(L_ERR "Got something strange: %d, %m", e);
return 0;
}
return 0;
/* Only one thing is actually supported for now: opening a listening socket */
int sfd = socket(AF_INET6, SOCK_STREAM, 0);
if (sfd < 0)
{
log(L_ERR "Failed to socket(): %m");
return 0;
}
while (1)
{
u32 r = (random_u32() % (32768-1024) + 1024);
union {
struct sockaddr_in6 sin;
struct sockaddr a;
} sin = {
.sin = {
.sin6_family = AF_INET6,
.sin6_port = htons(r),
.sin6_addr.s6_addr[15] = 1,
},
};
int e = bind(sfd, &sin.a, sizeof sin);
if (e < 0)
if (errno == EADDRINUSE)
{
log(L_INFO "Tried to bind to %u but already in use", r);
continue;
} else {
log(L_ERR "Failed to bind to %u: %m", r);
close(sfd);
return 0;
}
e = listen(sfd, 10);
if (e < 0)
{
log(L_ERR "Failed to listen(): %m", e);
close(sfd);
return 0;
}
log(L_INFO "SUCCESS");
byte outbuf[128];
linpool *lp = lp_new(sk->pool);
struct cbor_writer *cw = cbor_init(outbuf, sizeof outbuf, lp);
cbor_open_block_with_length(cw, 1);
cbor_add_int(cw, -2);
cbor_add_int(cw, r);
struct iovec v = {
.iov_base = outbuf,
.iov_len = cw->pt,
};
byte cbuf[CMSG_SPACE(sizeof sfd)];
struct msghdr m = {
.msg_iov = &v,
.msg_iovlen = 1,
.msg_control = &cbuf,
.msg_controllen = sizeof cbuf,
};
struct cmsghdr *c = CMSG_FIRSTHDR(&m);
c->cmsg_level = SOL_SOCKET;
c->cmsg_type = SCM_RIGHTS;
c->cmsg_len = CMSG_LEN(sizeof sfd);
memcpy(CMSG_DATA(c), &sfd, sizeof sfd);
e = sendmsg(sk->fd, &m, 0);
if (e < 0)
log(L_ERR "Failed to send socket: %m");
close(sfd);
return 0;
}
}
static void
@ -239,6 +389,7 @@ struct hexp_telnet_port {
const char *name;
uint hash;
uint port;
int fd;
};
static struct hexp_telnet {
@ -275,7 +426,10 @@ hexp_get_telnet(sock *s, const char *name)
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);
if (p->port)
return hexp_have_telnet(s, p);
else
return; /* Waiting for the exposed part */
uint8_t buf[64];
linpool *lp = lp_new(s->pool);