mirror of
https://github.com/tailscale/tailscale.git
synced 2026-04-06 23:53:43 -04:00
remove all allocs
This commit is contained in:
@@ -20,7 +20,7 @@ typedef struct iovec go_iovec;
|
||||
typedef struct sockaddr_in go_sockaddr_in;
|
||||
|
||||
// Wait for a completion to be available, fetch the data
|
||||
static int receive_into(int sock, struct io_uring *ring, char *ip, uint16_t *port) {
|
||||
static int receive_into(struct io_uring *ring) {
|
||||
struct io_uring_cqe *cqe;
|
||||
again:;
|
||||
|
||||
@@ -44,15 +44,18 @@ again:;
|
||||
return -1;
|
||||
}
|
||||
int n = cqe->res;
|
||||
|
||||
struct sockaddr_in *sa = (void *)mhdr->msg_name;
|
||||
memcpy(ip, &sa->sin_addr, 4);
|
||||
*port = ntohs(sa->sin_port);
|
||||
|
||||
io_uring_cqe_seen(ring, cqe);
|
||||
return n;
|
||||
}
|
||||
|
||||
static uint32_t ip(struct sockaddr_in *sa) {
|
||||
return ntohl(sa->sin_addr.s_addr);
|
||||
}
|
||||
|
||||
static uint16_t port(struct sockaddr_in *sa) {
|
||||
return ntohs(sa->sin_port);
|
||||
}
|
||||
|
||||
// submit a recvmsg request via liburing
|
||||
// TODO: What recvfrom support arrives, maybe use that instead?
|
||||
static int submit_recvmsg_request(int sock, struct io_uring *ring, struct msghdr *mhdr, struct iovec *iov, struct sockaddr_in *sender, char *buf, int buflen) {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
@@ -35,7 +36,7 @@ type UDPConn struct {
|
||||
file *os.File // must keep file from being GC'd
|
||||
fd C.int
|
||||
local net.Addr
|
||||
req req
|
||||
reqs [1]req
|
||||
}
|
||||
|
||||
func NewUDPConn(conn *net.UDPConn) (*UDPConn, error) {
|
||||
@@ -64,9 +65,11 @@ func NewUDPConn(conn *net.UDPConn) (*UDPConn, error) {
|
||||
fd: C.int(file.Fd()),
|
||||
local: conn.LocalAddr(),
|
||||
}
|
||||
if err := u.submitRequest(); err != nil {
|
||||
u.Close() // TODO: will this crash?
|
||||
return nil, err
|
||||
for i := range u.reqs[:1] {
|
||||
if err := u.submitRequest(&u.reqs[i]); err != nil {
|
||||
u.Close() // TODO: will this crash?
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return u, nil
|
||||
}
|
||||
@@ -75,14 +78,12 @@ type req struct {
|
||||
mhdr C.go_msghdr
|
||||
iov C.go_iovec
|
||||
sa C.go_sockaddr_in
|
||||
ip [4]byte // TODO: ipv6
|
||||
port C.uint16_t
|
||||
buf [device.MaxSegmentSize]byte
|
||||
}
|
||||
|
||||
func (u *UDPConn) submitRequest() error {
|
||||
func (u *UDPConn) submitRequest(r *req) error {
|
||||
// TODO: eventually separate submitting the request and waiting for the response.
|
||||
errno := C.submit_recvmsg_request(u.fd, u.ptr, &u.req.mhdr, &u.req.iov, &u.req.sa, (*C.char)(unsafe.Pointer(&u.req.buf[0])), C.int(len(u.req.buf)))
|
||||
errno := C.submit_recvmsg_request(u.fd, u.ptr, &r.mhdr, &r.iov, &r.sa, (*C.char)(unsafe.Pointer(&r.buf[0])), C.int(len(r.buf)))
|
||||
if errno < 0 {
|
||||
return fmt.Errorf("uring.submitRequest failed: %v", errno) // TODO: Improve
|
||||
}
|
||||
@@ -93,14 +94,20 @@ func (u *UDPConn) ReadFromNetaddr(buf []byte) (int, netaddr.IPPort, error) {
|
||||
if u.fd == 0 {
|
||||
return 0, netaddr.IPPort{}, errors.New("invalid uring.UDPConn")
|
||||
}
|
||||
n := C.receive_into(u.fd, u.ptr, (*C.char)(unsafe.Pointer(&u.req.ip)), &u.req.port)
|
||||
r := &u.reqs[0]
|
||||
n := C.receive_into(u.ptr)
|
||||
if n < 0 {
|
||||
return 0, netaddr.IPPort{}, errors.New("something wrong")
|
||||
}
|
||||
ipp := netaddr.IPPortFrom(netaddr.IPFrom4(u.req.ip), uint16(u.req.port))
|
||||
copy(buf, u.req.buf[:n])
|
||||
// TODO: this is broken :(((
|
||||
ip := C.ip(&r.sa)
|
||||
var ip4 [4]byte
|
||||
binary.BigEndian.PutUint32(ip4[:], uint32(ip))
|
||||
port := C.port(&r.sa)
|
||||
ipp := netaddr.IPPortFrom(netaddr.IPFrom4(ip4), uint16(port))
|
||||
copy(buf, r.buf[:n])
|
||||
// Queue up a new request.
|
||||
err := u.submitRequest()
|
||||
err := u.submitRequest(r)
|
||||
if err != nil {
|
||||
panic("how should we handle this?")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user