diff --git a/udt/readme.md b/udt/readme.md index 8e80dc1..9bd8133 100644 --- a/udt/readme.md +++ b/udt/readme.md @@ -19,6 +19,16 @@ while the messaging semantics can be regarded as a subset of SCTP [RFC4960]. ``` +From `udtSocket.Read`: + +``` +// for datagram sockets, block until we have a message to return and then return it +// if the buffer isn't big enough, return a truncated message (discarding the rest) and return an error + +// for streaming sockets, block until we have at least something to return, then +// fill up the passed buffer as far as we can without blocking again +``` + ## Deviations MTU negotiation is disabled. Peernet uses a hardcoded max packet size (see protocol package). Packets may be routed through any network adapter, therefore pinning a MTU specific to a network adapter would not make much sense. diff --git a/udt/udtsocket.go b/udt/udtsocket.go index 20a764e..50edae8 100644 --- a/udt/udtsocket.go +++ b/udt/udtsocket.go @@ -198,7 +198,7 @@ func (s *udtSocket) Read(p []byte) (n int, err error) { } n = copy(p, msg) if n < len(msg) { - err = errors.New("Message truncated") + err = errors.New("Message truncated") // <- evil buggy } } else { // for streaming sockets, block until we have at least something to return, then @@ -260,7 +260,10 @@ func (s *udtSocket) Write(p []byte) (n int, err error) { return } + // previous bug: io.Writer documentation says "Implementations must not retain p.", but it was passed on in s.messageOut n = len(p) + data := make([]byte, n) + copy(data, p) for { if s.writeDeadlinePassed { @@ -272,7 +275,7 @@ func (s *udtSocket) Write(p []byte) (n int, err error) { deadline = s.writeDeadline.C } select { - case s.messageOut <- sendMessage{content: p, tim: time.Now()}: + case s.messageOut <- sendMessage{content: data, tim: time.Now()}: // send successful return case _, ok := <-deadline: