// Note: The multiplexer is no longer a multiplexer. Before, it tried send out future UDT traffic over an old (invalidated) PacketConn. package udt import ( "math/rand" "github.com/PeernetOfficial/core/udt/packet" ) // A multiplexer is a single UDT socket over a single PacketConn. type multiplexer struct { socket *UDTSocket // Socket socketID uint32 // Socket ID listenSock *listener // the server socket listening to incoming connections, if there is one. Set by caller. maxPacketSize uint // the Maximum Transmission Unit of packets sent from this address incomingData <-chan []byte // source to read packets from outgoingData chan<- []byte // destination to send packets to terminationSignal <-chan struct{} // external termination signal to watch closer Closer // external closer to call in case the local socket/listener closes } // The closer is called when the socket/listener closes. The terminationSignal is an external (upstream) signal to watch for. func newMultiplexer(closer Closer, maxPacketSize uint, incomingData <-chan []byte, outgoingData chan<- []byte, terminationSignal <-chan struct{}) (m *multiplexer) { m = &multiplexer{ maxPacketSize: maxPacketSize, closer: closer, incomingData: incomingData, outgoingData: outgoingData, terminationSignal: terminationSignal, } go m.goRead() return } func (m *multiplexer) newSocket(config *Config, isServer bool, isDatagram bool) (s *UDTSocket) { m.socketID = rand.Uint32() m.socket = newSocket(m, config, m.socketID, isServer, isDatagram) return m.socket } // read runs in a goroutine and reads packets from conn using a buffer from the readBufferPool, or a new buffer. func (m *multiplexer) goRead() { for { var buf []byte select { case buf = <-m.incomingData: case <-m.terminationSignal: if m.socket != nil { m.socket.Terminate() // Pass the external termination signal down to the socket. This makes sure any pending reader on the socket (especially if blocking) returns with EOF. } return } p, err := packet.DecodePacket(buf) if err != nil { //fmt.Printf("Error decoding UDT packet: %s\n", err) return } // attempt to route the packet sockID := p.SocketID() if sockID == 0 { var hsPacket *packet.HandshakePacket var ok bool if hsPacket, ok = p.(*packet.HandshakePacket); !ok { //fmt.Printf("Received non-handshake packet with destination socket = 0\n") return } if m.listenSock != nil { m.listenSock.readHandshake(m, hsPacket) } } if m.socketID == sockID && m.socket != nil { m.socket.readPacket(m, p) } } } func (m *multiplexer) sendPacket(destSockID uint32, ts uint32, p packet.Packet) { p.SetHeader(destSockID, ts) if destSockID == 0 { if _, ok := p.(*packet.HandshakePacket); !ok { //fmt.Printf("Sending non-handshake packet with destination socket = 0\n") return } } if m.socket != nil { m.socket.recordTypeOfPacket(p, true) } buf := make([]byte, m.maxPacketSize) plen, err := p.WriteTo(buf) // encode if err != nil { //fmt.Printf("Error encoding UDT packet: %s\n", err.Error()) return } select { case m.outgoingData <- buf[0:plen]: case <-m.terminationSignal: return } }