mirror of
https://github.com/yggdrasil-network/yggdrasil-go.git
synced 2025-04-29 06:35:07 +03:00
Rename awdl.go to link.go, add stream.go, update tcp.go
This commit is contained in:
parent
f6cb194d5c
commit
6fe3b01e90
4 changed files with 177 additions and 129 deletions
111
src/yggdrasil/stream.go
Normal file
111
src/yggdrasil/stream.go
Normal file
|
@ -0,0 +1,111 @@
|
|||
package yggdrasil
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/util"
|
||||
)
|
||||
|
||||
type stream struct {
|
||||
buffer []byte
|
||||
cursor int
|
||||
}
|
||||
|
||||
const streamMsgSize = 2048 + 65535
|
||||
|
||||
var streamMsg = [...]byte{0xde, 0xad, 0xb1, 0x75} // "dead bits"
|
||||
|
||||
func (s *stream) init() {
|
||||
s.buffer = make([]byte, 2*streamMsgSize)
|
||||
s.cursor = 0
|
||||
}
|
||||
|
||||
// This reads from the channel into a []byte buffer for incoming messages. It
|
||||
// copies completed messages out of the cache into a new slice, and passes them
|
||||
// to the peer struct via the provided `in func([]byte)` argument. Then it
|
||||
// shifts the incomplete fragments of data forward so future reads won't
|
||||
// overwrite it.
|
||||
func (s *stream) write(bs []byte, in func([]byte)) error {
|
||||
frag := s.buffer[:0]
|
||||
if n := len(bs); n > 0 {
|
||||
frag = append(frag, bs[:n]...)
|
||||
msg, ok, err2 := stream_chopMsg(&frag)
|
||||
if err2 != nil {
|
||||
return fmt.Errorf("message error: %v", err2)
|
||||
}
|
||||
if !ok {
|
||||
// We didn't get the whole message yet
|
||||
return nil
|
||||
}
|
||||
newMsg := append(util.GetBytes(), msg...)
|
||||
in(newMsg)
|
||||
util.Yield()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// This takes a pointer to a slice as an argument. It checks if there's a
|
||||
// complete message and, if so, slices out those parts and returns the message,
|
||||
// true, and nil. If there's no error, but also no complete message, it returns
|
||||
// nil, false, and nil. If there's an error, it returns nil, false, and the
|
||||
// error, which the reader then handles (currently, by returning from the
|
||||
// reader, which causes the connection to close).
|
||||
func stream_chopMsg(bs *[]byte) ([]byte, bool, error) {
|
||||
// Returns msg, ok, err
|
||||
if len(*bs) < len(streamMsg) {
|
||||
return nil, false, nil
|
||||
}
|
||||
for idx := range streamMsg {
|
||||
if (*bs)[idx] != streamMsg[idx] {
|
||||
return nil, false, errors.New("bad message")
|
||||
}
|
||||
}
|
||||
msgLen, msgLenLen := wire_decode_uint64((*bs)[len(streamMsg):])
|
||||
if msgLen > streamMsgSize {
|
||||
return nil, false, errors.New("oversized message")
|
||||
}
|
||||
msgBegin := len(streamMsg) + msgLenLen
|
||||
msgEnd := msgBegin + int(msgLen)
|
||||
if msgLenLen == 0 || len(*bs) < msgEnd {
|
||||
// We don't have the full message
|
||||
// Need to buffer this and wait for the rest to come in
|
||||
return nil, false, nil
|
||||
}
|
||||
msg := (*bs)[msgBegin:msgEnd]
|
||||
(*bs) = (*bs)[msgEnd:]
|
||||
return msg, true, nil
|
||||
}
|
||||
|
||||
/*
|
||||
func (s *stream) chopMsg() ([]byte, bool, error) {
|
||||
// Returns msg, ok, err
|
||||
if len(s.buffer) < len(streamMsg) {
|
||||
fmt.Println("*** too short")
|
||||
return nil, false, nil
|
||||
}
|
||||
for idx := range streamMsg {
|
||||
if s.buffer[idx] != streamMsg[idx] {
|
||||
fmt.Println("*** bad message")
|
||||
return nil, false, errors.New("bad message")
|
||||
}
|
||||
}
|
||||
msgLen, msgLenLen := wire_decode_uint64((s.buffer)[len(streamMsg):])
|
||||
if msgLen > streamMsgSize {
|
||||
fmt.Println("*** oversized message")
|
||||
return nil, false, errors.New("oversized message")
|
||||
}
|
||||
msgBegin := len(streamMsg) + msgLenLen
|
||||
msgEnd := msgBegin + int(msgLen)
|
||||
if msgLenLen == 0 || len(s.buffer) < msgEnd {
|
||||
// We don't have the full message
|
||||
// Need to buffer this and wait for the rest to come in
|
||||
fmt.Println("*** still waiting")
|
||||
return nil, false, nil
|
||||
}
|
||||
msg := s.buffer[msgBegin:msgEnd]
|
||||
s.buffer = s.buffer[msgEnd:]
|
||||
fmt.Println("*** done")
|
||||
return msg, true, nil
|
||||
}
|
||||
*/
|
Loading…
Add table
Add a link
Reference in a new issue