remove all allocs

This commit is contained in:
Josh Bleecher Snyder
2021-06-01 21:20:09 -07:00
parent b83ac004f1
commit 71f35bda1a
2 changed files with 28 additions and 18 deletions

View File

@@ -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) {

View File

@@ -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?")
}