mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 17:51:53 +00:00
Flock: Telnet connection to hypervisor seems to work well
This commit is contained in:
parent
b6aca48277
commit
19dae2c622
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "flock/flock.h"
|
#include "flock/flock.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -132,17 +133,87 @@ static struct hypervisor_exposed {
|
|||||||
/**
|
/**
|
||||||
* Exposed process' parent side (requestor)
|
* 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
|
static int
|
||||||
hypervisor_exposed_parent_rx(sock *sk, uint size UNUSED)
|
hypervisor_exposed_parent_rx(sock *sk, uint size UNUSED)
|
||||||
{
|
{
|
||||||
log(L_INFO "HV EP RX");
|
int sfd = -1;
|
||||||
recvmsg(sk->fd, NULL, 0);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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,
|
.msg_iovlen = 1,
|
||||||
};
|
};
|
||||||
int e = recvmsg(sk->fd, &m, 0);
|
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
|
static void
|
||||||
@ -239,6 +389,7 @@ struct hexp_telnet_port {
|
|||||||
const char *name;
|
const char *name;
|
||||||
uint hash;
|
uint hash;
|
||||||
uint port;
|
uint port;
|
||||||
|
int fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct hexp_telnet {
|
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;
|
uint h = name ? mem_hash(name, strlen(name)) : 0;
|
||||||
struct hexp_telnet_port *p = HASH_FIND(hexp_telnet.port_hash, HEXP_TELNET, name, h);
|
struct hexp_telnet_port *p = HASH_FIND(hexp_telnet.port_hash, HEXP_TELNET, name, h);
|
||||||
if (p)
|
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];
|
uint8_t buf[64];
|
||||||
linpool *lp = lp_new(s->pool);
|
linpool *lp = lp_new(s->pool);
|
||||||
|
Loading…
Reference in New Issue
Block a user