Skip to content

Data corruption using WriteFixed #4

@ImVexed

Description

@ImVexed

Using this code:

import (
	"unsafe"

	"github.com/hodgesds/iouring-go"
)

type netring struct {
	ring *iouring.Ring
}

func newNetRing() (*netring, error) {
	ring, err := iouring.New(1024)

	if err != nil {
		return nil, err
	}

	return &netring{
		ring,
	}, nil
}

func (n *netring) send(fds []int32, data []byte) error {
	addr := (uint64)(uintptr(unsafe.Pointer(&data[0])))
	length := uint32(len(data))

	for _, fd := range fds {
		e, commit := n.ring.SubmitEntry()

		e.Opcode = iouring.WriteFixed
		e.Fd = fd
		e.Addr = addr
		e.Len = length

		commit()
	}

	return n.ring.Enter(uint(len(fds)), uint(len(fds)), iouring.EnterGetEvents, nil)
}

I'm consistently getting data overwritten as it's sent to the client. I had a test that opens 1000 connections which all get the same WriteFixed submit entry, however upon looking at what they receive:

...
{"id":73,"roomId":1,"userId":876,"authorName":"Spam User 876","content":"...","createdAt":"2020-05-06T05:28:17.19695Z"}
{"id":73,"roomId":1,"userId":876,"authorName":"Spam User 876","content":"...","createdAt":"2020-05-06T05:28:17.19695Z"}
{"id":73,"roomId":1,"userId":876,"authorName":"Spam User 876","content":"...","createdAt":"2020-05-06T05:28:17.19695Z"}
{"id":73,"roomId":1,"userId":876,"authorName":"Spam User 876","content":"...{"id":73,"roomId":1,"userId":876,"authorName":"Spam User 876","content":"...

You'll see that we receive the message properly for some clients, but will occasionally receive a message like the last, where the end of the message is seemingly overwritten by the message.

I've ensured that there are no duplicate file descriptors causing 2 writes to be queued in the same ring for the same fd.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions