示例#1
0
func main() {

	go func() {
		var addr net.Addr
		var udp *net.UDPConn
		var err error
		if addr, err = net.ResolveUDPAddr("udp4", ":1234"); err != nil {
			panic(err)
		}
		if udp, err = net.ListenUDP("udp", addr.(*net.UDPAddr)); err != nil {
			panic(err)
		}
		var buf = make([]byte, 65535)
		n, addr, e := udp.ReadFrom(buf)
		if e != nil {
			panic(e)
		}
		udp.WriteTo(buf[:n], addr)
	}()
	runtime.Gosched()
	svr := NewPortalSvr()
	svr.basAddr = "127.0.0.1:1234"
	svr.basSecret = []byte("xxffe")
	if err := svr.Listen(":1288"); err != nil {
		panic(err)
	}
	svr.Run()
	err := svr.Auth("aas", "asas1", "255.255.255.255:1223")
	if err != nil {
		println(err.Error())
	}
}
示例#2
0
func serverRead(t *testing.T, server *net.UDPConn) string {
	bytes := make([]byte, 1024)
	n, _, err := server.ReadFrom(bytes)
	if err != nil {
		t.Fatal(err)
	}
	return string(bytes[:n])
}
示例#3
0
// readFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a
// net.UDPAddr.
func readFromSessionUDP(conn *net.UDPConn, b []byte) (int, *sessionUDP, error) {
	n, raddr, err := conn.ReadFrom(b)
	if err != nil {
		return n, nil, err
	}
	session := &sessionUDP{raddr.(*net.UDPAddr)}
	return n, session, err
}
示例#4
0
func waitforudp(conn *net.UDPConn, channel chan bool) {
	message := make([]byte, maxUDPsize)
	for { // ever...
		n, remaddr, error := conn.ReadFrom(message)
		checkError("Cannot read from", error)
		go handleudp(conn, remaddr, message[0:n])
	}
	channel <- true
}
示例#5
0
func TestHandlePing(t *testing.T) {
	m := GetMemberlist(t)
	m.config.EnableCompression = false
	defer m.Shutdown()

	var udp *net.UDPConn
	for port := 60000; port < 61000; port++ {
		udpAddr := fmt.Sprintf("127.0.0.1:%d", port)
		udpLn, err := net.ListenPacket("udp", udpAddr)
		if err == nil {
			udp = udpLn.(*net.UDPConn)
			break
		}
	}

	if udp == nil {
		t.Fatalf("no udp listener")
	}

	// Encode a ping
	ping := ping{SeqNo: 42}
	buf, err := encode(pingMsg, ping)
	if err != nil {
		t.Fatalf("unexpected err %s", err)
	}

	// Send
	addr := &net.UDPAddr{IP: net.ParseIP(m.config.BindAddr), Port: m.config.BindPort}
	udp.WriteTo(buf.Bytes(), addr)

	// Wait for response
	go func() {
		time.Sleep(time.Second)
		panic("timeout")
	}()

	in := make([]byte, 1500)
	n, _, err := udp.ReadFrom(in)
	if err != nil {
		t.Fatalf("unexpected err %s", err)
	}
	in = in[0:n]

	msgType := messageType(in[0])
	if msgType != ackRespMsg {
		t.Fatalf("bad response %v", in)
	}

	var ack ackResp
	if err := decode(in[1:], &ack); err != nil {
		t.Fatalf("unexpected err %s", err)
	}

	if ack.SeqNo != 42 {
		t.Fatalf("bad sequence no")
	}
}
示例#6
0
文件: packet.go 项目: jimlloyd/mbus
func Listen(conn *net.UDPConn, incoming chan<- Packet) error {
	for {
		data := make([]byte, 8192)
		size, remote, err := conn.ReadFrom(data)
		if err != nil {
			panic(err)
		}
		incoming <- Packet{data[0:size], remote}
	}
}
示例#7
0
func udpEchoHandler(c *net.UDPConn) {
	buf := make([]byte, 64)
	for {
		n, addr, err := c.ReadFrom(buf)
		if err != nil {
			return
		}
		if _, err = c.WriteTo(buf[0:n], addr); err != nil {
			return
		}
	}
}
示例#8
0
func ReadUdpConnections(conn *net.UDPConn) {

	contexts := make(map[string]*UdpContext)

	var buffer [1024]byte
	for {
		n, addr, err := conn.ReadFrom(buffer[:])
		if err != nil {
			log.Printf("Failed to read from udp socket: %s\n", err)
			continue
		}

		key := addr.String()

		context := contexts[key]

		if context == nil {
			// New request
			message := string(buffer[:n])
			context, err := CreateContext(addr, message)
			if err != nil {
				log.Printf("Failed to start udp session: %s\n", err)
				continue
			}

			contexts[key] = context

			// Start
			if context.command == "get" {
				HandleUdpGet(conn, context)
			}
			if context.command == "get" {
				HandleUdpPut(conn, context)
			}
		} else if context.command == "get" {
			message := string(buffer[:n])

			// Flow-control: only allow one outstanding message at a time. Wait for an ack after every request.
			if message != "get-ack" {
				log.Println("Protocol error: expected get-ack")
				continue
			}
			GetSend(conn, context)
		} else if context.command == "put" {

			message := string(buffer[:n])
			context.length = context.length - PutRecv(conn, context)
		}
	}
}
示例#9
0
文件: server.go 项目: edc1591/gohome
// recv is a long running routine to receive packets from an interface
func (s *Server) recv(c *net.UDPConn) {
	if c == nil {
		return
	}
	buf := make([]byte, 65536)
	for !s.shouldShutdown {
		n, from, err := c.ReadFrom(buf)
		if err != nil {
			continue
		}
		if err := s.parsePacket(buf[:n], from); err != nil {
			log.Printf("[ERR] bonjour: Failed to handle query: %v", err)
		}
	}
}
示例#10
0
func (conn *Connection) Read(socket *net.UDPConn) {
	b := make([]byte, defaultReadSize)

	for {
		n, addr, err := socket.ReadFrom(b)
		conn.lastErr = err

		if conn.IsError() {
			close(conn.Datagrams)
			break
		}

		conn.Datagrams <- Datagram{addr, b[0:n]}
	}
}
示例#11
0
func TestIngestPacket_CRC(t *testing.T) {
	m := GetMemberlist(t)
	m.config.EnableCompression = false
	defer m.Shutdown()

	var udp *net.UDPConn
	for port := 60000; port < 61000; port++ {
		udpAddr := fmt.Sprintf("127.0.0.1:%d", port)
		udpLn, err := net.ListenPacket("udp", udpAddr)
		if err == nil {
			udp = udpLn.(*net.UDPConn)
			break
		}
	}

	if udp == nil {
		t.Fatalf("no udp listener")
	}

	// Get a message with a checksum
	payload := []byte{3, 3, 3, 3}
	m.rawSendMsgUDP(udp.LocalAddr(), &Node{PMax: 5}, payload)

	in := make([]byte, 1500)
	n, _, err := udp.ReadFrom(in)
	if err != nil {
		t.Fatalf("unexpected err %s", err)
	}
	in = in[0:n]

	if len(in) != 9 {
		t.Fatalf("bad: %v", in)
	}

	// Corrupt the checksum
	in[1] <<= 1

	logs := &bytes.Buffer{}
	logger := log.New(logs, "", 0)
	m.logger = logger
	m.ingestPacket(in, udp.LocalAddr(), time.Now())

	if !strings.Contains(logs.String(), "invalid checksum") {
		t.Fatalf("bad: %s", logs.String())
	}
}
示例#12
0
//Called by MulticastInit
//All received messsages piped to buffered channel
func multicastListen(recv chan<- Message, conn *net.UDPConn) {
	for {
		buf := make([]byte, 512)
		l, _, err := conn.ReadFrom(buf)
		if err != nil {
			fmt.Println("NET: ", err)
		}
		var m Message
		err = json.Unmarshal(buf[:l], &m)
		if err != nil {
			fmt.Println("JSON unpacking: ", err)
		} else {
			m.TimeRecv = time.Now()
			recv <- m
		}
	}
}
示例#13
0
func readAndWriteUDP(r io.Reader, w io.Writer, con *net.UDPConn, ra net.Addr, verbose bool) <-chan net.Addr {
	buf := make([]byte, BUFFER_LIMIT)
	cAddr := make(chan net.Addr)
	go func() {
		defer func() {
			con.Close()
			cAddr <- ra
		}()

		for {
			var bytesread int
			var errRead, errWrite error
			if con, ok := r.(*net.UDPConn); ok {
				var addr net.Addr
				bytesread, addr, errRead = con.ReadFrom(buf)
				if con.RemoteAddr() == nil && ra == nil {
					ra = addr
					cAddr <- ra
				}
			} else {
				bytesread, errRead = r.Read(buf)
			}
			if errRead != nil {
				if errRead != io.EOF {
					if verbose {
						log.Println("READ ERROR: ", errRead)
					}
				}
				break
			}
			if con, ok := w.(*net.UDPConn); ok && con.RemoteAddr() == nil {
				_, errWrite = con.WriteTo(buf[0:bytesread], ra)
			} else {
				_, errWrite = w.Write(buf[0:bytesread])
			}
			if errWrite != nil {
				if verbose {
					log.Println("WRITE ERROR: ", errWrite)
				}
				return
			}
		}
	}()
	return cAddr
}
示例#14
0
文件: dns2tcp.go 项目: riscie/dns2tcp
func dnsListen(conn net.UDPConn) {
	buf := make([]byte, 1024)
	n, addr, err := conn.ReadFrom(buf)
	log.Print("Addr", addr)

	if err != nil {
		log.Fatal(err)
	}
	log.Printf("Data come in from: %s", addr)

	reply := dnsRequest(buf[0:n])
	_, err = conn.WriteTo(reply, addr)
	if err != nil {
		log.Fatal(err)
	} else {
		log.Print("=====EOF=====")
	}
}
示例#15
0
//异步运行服务器,返回Closer以便可以关闭服务器,所有无法运行的错误panic出来,其他错误丢到kmgLog error里面.
func RunServerWithPacketHandler(address string, secret []byte, handler PacketHandler) func() error {
	connChan := make(chan *net.UDPConn)
	go func() {
		var conn *net.UDPConn
		addr, err := net.ResolveUDPAddr("udp", address)
		if err != nil {
			panic(err)
		}
		conn, err = net.ListenUDP("udp", addr)
		if err != nil {
			panic(err)
		}
		connChan <- conn
		for {
			b := make([]byte, 4096)
			n, senderAddress, err := conn.ReadFrom(b)
			if err != nil {
				panic(err)
			}
			go func(p []byte, senderAddress net.Addr) {
				pac, err := DecodeRequestPacket(secret, p)
				if err != nil {
					kmgLog.Log("error", "radius.Decode", err.Error())
					return
				}

				npac := handler(pac)
				if npac == nil {
					// 特殊情况,返回nil,表示抛弃这个包.
					return
				}
				err = npac.Send(conn, senderAddress)
				if err != nil {
					kmgLog.Log("error", "radius.Send", err.Error())
					return
				}
			}(b[:n], senderAddress)
		}
		return
	}()
	conn := <-connChan
	close(connChan)
	return conn.Close
}
示例#16
0
文件: server.go 项目: sysbot/curvecp
func readLoop(sock *net.UDPConn, packetIn chan<- packet) {
	pb := freelist.Packets.Get()
	for {
		// CurveCP datagrams are specified to always fit in the
		// smallest IPv6 datagram, 1280 bytes.
		n, addr, err := sock.ReadFrom(pb)
		if err != nil {
			// TODO: possibly be more discerning about when to return.
			return
		}
		if n < 64 {
			// Packet too small to be any CurveCP packet, discard.
			continue
		}

		pb = pb[:n]
		// messageMagic first, since it's the most common.
		packetIn <- packet{addr, pb}
		pb = freelist.Packets.Get()
	}
}
示例#17
0
文件: tcpudp.go 项目: xiaobagou/echo
func handleUDPConn(udpconn *net.UDPConn, key []byte, receiveData []byte) {
	//udpconn.SetReadDeadline(time.Now().Add(time.Duration(20) * time.Second))
	receiveDatalen, addr, err := udpconn.ReadFrom(receiveData)
	if err != nil {
		log.Printf("udpconn ReadFrom err : %v\n", err)
	}

	receiveData, err = netstring.Unmarshall(receiveData[:receiveDatalen])
	if err != nil {
		log.Printf("netstring unmarshall error : %v\n", err)
		return
	}

	_, err = libsodium.DecryptData(key, receiveData)
	if err != nil {
		log.Printf("udp DecryptData error : %v\n", err)
		return
	}

	homeip = addr.String()
}
示例#18
0
func TestHandlePing_WrongNode(t *testing.T) {
	m := GetMemberlist(t)
	m.config.EnableCompression = false
	defer m.Shutdown()

	var udp *net.UDPConn
	for port := 60000; port < 61000; port++ {
		udpAddr := fmt.Sprintf("127.0.0.1:%d", port)
		udpLn, err := net.ListenPacket("udp", udpAddr)
		if err == nil {
			udp = udpLn.(*net.UDPConn)
			break
		}
	}

	if udp == nil {
		t.Fatalf("no udp listener")
	}

	// Encode a ping, wrong node!
	ping := ping{SeqNo: 42, Node: m.config.Name + "-bad"}
	buf, err := encode(pingMsg, ping)
	if err != nil {
		t.Fatalf("unexpected err %s", err)
	}

	// Send
	addr := &net.UDPAddr{IP: net.ParseIP(m.config.BindAddr), Port: m.config.BindPort}
	udp.WriteTo(buf.Bytes(), addr)

	// Wait for response
	udp.SetDeadline(time.Now().Add(50 * time.Millisecond))
	in := make([]byte, 1500)
	_, _, err = udp.ReadFrom(in)

	// Should get an i/o timeout
	if err == nil {
		t.Fatalf("expected err %s", err)
	}
}
示例#19
0
func receiveGoroutine(conn *net.UDPConn, ch chan<- int) {
	var count uint32 = 1

	for i := 0; i < 2; i++ {
		var data [1024]byte

		_, addr, err := conn.ReadFrom(data[:])
		if err != nil {
			log.Printf("Recv: %v", err)
		}

		buf := bytes.NewBuffer(data[:])
		err = binary.Read(buf, binary.BigEndian, &count)
		if err != nil {
			log.Printf("Buffer: %v\n", err)
			break
		}
		log.Printf("Receive From Client %d\n", count)

		count++

		bufW := new(bytes.Buffer)
		err = binary.Write(bufW, binary.LittleEndian, count)
		if err != nil {
			log.Printf("Buffer: %v\n", err)
		}
		_, err = conn.WriteTo(bufW.Bytes(), addr)
		if err != nil {
			log.Printf("Send: %v\n", err)
			break
		}

	}

	if err := conn.Close(); err != nil {
		log.Printf("Close: %v\n", err)
	}

	ch <- 1
}
示例#20
0
// Data receiving routine reads from connection, unpacks packets into dns.Msg
// structures and sends them to a given msgCh channel
func (c *client) recv(l *net.UDPConn, msgCh chan *dns.Msg) {
	if l == nil {
		return
	}
	buf := make([]byte, 65536)
	for !c.closed {
		n, _, err := l.ReadFrom(buf)
		if err != nil {
			continue
		}
		msg := new(dns.Msg)
		if err := msg.Unpack(buf[:n]); err != nil {
			log.Printf("[ERR] mdns: Failed to unpack packet: %v", err)
			continue
		}
		select {
		case msgCh <- msg:
		case <-c.closedCh:
			return
		}
	}
}
示例#21
0
func genericReader(conn *net.UDPConn, outbox chan<- recv) {
	bs := make([]byte, 65536)
	for {
		n, addr, err := conn.ReadFrom(bs)
		if err != nil {
			l.Warnln("multicast read:", err)
			return
		}
		if debug {
			l.Debugf("recv %d bytes from %s", n, addr)
		}

		c := make([]byte, n)
		copy(c, bs)
		select {
		case outbox <- recv{c, addr}:
		default:
			if debug {
				l.Debugln("dropping message")
			}
		}
	}
}
示例#22
0
文件: main.go 项目: pablomelo/gmd
func rd(out chan string, conn *net.UDPConn, quit chan struct{}) {
	log.Printf("rd: %s", conn.LocalAddr())
	defer log.Printf("rd: done")
	const maxSize = 4096
	for {
		select {
		case <-quit:
			return

		default:
			b := make([]byte, maxSize)
			conn.SetReadDeadline(time.Now().Add(cycle))
			n, remoteAddr, err := conn.ReadFrom(b)
			if err != nil {
				continue
			}
			if n >= maxSize {
				log.Printf("%s: too big", remoteAddr)
				continue
			}
			out <- string(b[:n])
		}
	}
}
示例#23
0
文件: server.go 项目: Gaboose/mdns
// recv is a long running routine to receive packets from an interface
func (s *Server) recv(c *net.UDPConn) {
	if c == nil {
		return
	}
	buf := make([]byte, 65536)
	var shutdown bool
	s.shutdownLock.RLock()
	defer s.shutdownLock.RUnlock()
	for {
		s.shutdownLock.RLock()
		shutdown = s.shutdown
		s.shutdownLock.RUnlock()
		if shutdown {
			break
		}
		n, from, err := c.ReadFrom(buf)
		if err != nil {
			continue
		}
		if err := s.parsePacket(buf[:n], from); err != nil {
			Log.Printf("[ERR] mdns: Failed to handle query: %v", err)
		}
	}
}
示例#24
0
func TestHandleIndirectPing(t *testing.T) {
	m := GetMemberlist(t)
	m.config.EnableCompression = false
	defer m.Shutdown()

	var udp *net.UDPConn
	for port := 60000; port < 61000; port++ {
		udpAddr := fmt.Sprintf("127.0.0.1:%d", port)
		udpLn, err := net.ListenPacket("udp", udpAddr)
		if err == nil {
			udp = udpLn.(*net.UDPConn)
			break
		}
	}

	if udp == nil {
		t.Fatalf("no udp listener")
	}

	// Encode an indirect ping
	ind := indirectPingReq{
		SeqNo:  100,
		Target: net.ParseIP(m.config.BindAddr),
		Port:   uint16(m.config.BindPort),
	}
	buf, err := encode(indirectPingMsg, &ind)
	if err != nil {
		t.Fatalf("unexpected err %s", err)
	}

	// Send
	addr := &net.UDPAddr{IP: net.ParseIP(m.config.BindAddr), Port: m.config.BindPort}
	udp.WriteTo(buf.Bytes(), addr)

	// Wait for response
	doneCh := make(chan struct{}, 1)
	go func() {
		select {
		case <-doneCh:
		case <-time.After(2 * time.Second):
			panic("timeout")
		}
	}()

	in := make([]byte, 1500)
	n, _, err := udp.ReadFrom(in)
	if err != nil {
		t.Fatalf("unexpected err %s", err)
	}
	in = in[0:n]

	msgType := messageType(in[0])
	if msgType != ackRespMsg {
		t.Fatalf("bad response %v", in)
	}

	var ack ackResp
	if err := decode(in[1:], &ack); err != nil {
		t.Fatalf("unexpected err %s", err)
	}

	if ack.SeqNo != 100 {
		t.Fatalf("bad sequence no")
	}

	doneCh <- struct{}{}
}
示例#25
0
func TestRawSendUdp_CRC(t *testing.T) {
	m := GetMemberlist(t)
	m.config.EnableCompression = false
	defer m.Shutdown()

	var udp *net.UDPConn
	for port := 60000; port < 61000; port++ {
		udpAddr := fmt.Sprintf("127.0.0.1:%d", port)
		udpLn, err := net.ListenPacket("udp", udpAddr)
		if err == nil {
			udp = udpLn.(*net.UDPConn)
			break
		}
	}

	if udp == nil {
		t.Fatalf("no udp listener")
	}

	// Pass a nil node with no nodes registered, should result in no checksum
	payload := []byte{3, 3, 3, 3}
	m.rawSendMsgUDP(udp.LocalAddr(), nil, payload)

	in := make([]byte, 1500)
	n, _, err := udp.ReadFrom(in)
	if err != nil {
		t.Fatalf("unexpected err %s", err)
	}
	in = in[0:n]

	if len(in) != 4 {
		t.Fatalf("bad: %v", in)
	}

	// Pass a non-nil node with PMax >= 5, should result in a checksum
	m.rawSendMsgUDP(udp.LocalAddr(), &Node{PMax: 5}, payload)

	in = make([]byte, 1500)
	n, _, err = udp.ReadFrom(in)
	if err != nil {
		t.Fatalf("unexpected err %s", err)
	}
	in = in[0:n]

	if len(in) != 9 {
		t.Fatalf("bad: %v", in)
	}

	// Register a node with PMax >= 5 to be looked up, should result in a checksum
	m.nodeMap["127.0.0.1"] = &nodeState{
		Node: Node{PMax: 5},
	}
	m.rawSendMsgUDP(udp.LocalAddr(), nil, payload)

	in = make([]byte, 1500)
	n, _, err = udp.ReadFrom(in)
	if err != nil {
		t.Fatalf("unexpected err %s", err)
	}
	in = in[0:n]

	if len(in) != 9 {
		t.Fatalf("bad: %v", in)
	}
}
示例#26
0
文件: server.go 项目: rwl4/syslog
func (s *Server) receiver(c *net.UDPConn) {
	//q := (chan<- Message)(s.q)
	buf := make([]byte, 1024)
	for {
		n, addr, err := c.ReadFrom(buf)
		if err != nil {
			if !s.shutdown {
				s.l.Fatalln("Read error:", err)
			}
			return
		}
		pkt := buf[:n]

		m := new(Message)
		m.Source = addr
		m.Time = time.Now()

		// Parse priority (if exists)
		prio := 13 // default priority
		hasPrio := false
		if pkt[0] == '<' {
			n = 1 + bytes.IndexByte(pkt[1:], '>')
			if n > 1 && n < 5 {
				p, err := strconv.Atoi(string(pkt[1:n]))
				if err == nil && p >= 0 {
					hasPrio = true
					prio = p
					pkt = pkt[n+1:]
				}
			}
		}
		m.Severity = Severity(prio & 0x07)
		m.Facility = Facility(prio >> 3)

		// Parse header (if exists)
		if hasPrio && len(pkt) >= 16 && pkt[15] == ' ' {
			// Get timestamp
			layout := "Jan _2 15:04:05"
			ts, err := time.Parse(layout, string(pkt[:15]))
			if err == nil && !ts.IsZero() {
				// Get hostname
				n = 16 + bytes.IndexByte(pkt[16:], ' ')
				if n != 15 {
					m.Timestamp = ts
					m.Hostname = string(pkt[16:n])
					pkt = pkt[n+1:]
				}
			}
			// TODO: check for version an new format of header as
			// described in RFC 5424.
		}

		// Parse msg part
		pkt = bytes.TrimRightFunc(pkt, isNulCrLf)
		n = bytes.IndexFunc(pkt, isNotAlnum)
		if n != -1 {
			m.Tag = string(pkt[:n])
			pkt = pkt[n:]
		}
		m.Content = string(pkt)

		s.passToHandlers(m)
	}
}
示例#27
0
func TestSendMsg_Piggyback(t *testing.T) {
	m := GetMemberlist(t)
	defer m.Shutdown()

	// Add a message to be broadcast
	a := alive{
		Incarnation: 10,
		Node:        "rand",
		Addr:        []byte{127, 0, 0, 255},
		Meta:        nil,
	}
	m.encodeAndBroadcast("rand", aliveMsg, &a)

	var udp *net.UDPConn
	for port := 60000; port < 61000; port++ {
		udpAddr := fmt.Sprintf("127.0.0.1:%d", port)
		udpLn, err := net.ListenPacket("udp", udpAddr)
		if err == nil {
			udp = udpLn.(*net.UDPConn)
			break
		}
	}

	// Encode a ping
	ping := ping{SeqNo: 42}
	buf, err := encode(pingMsg, ping)
	if err != nil {
		t.Fatalf("unexpected err %s", err)
	}

	// Send
	addr := &net.UDPAddr{IP: net.ParseIP(m.config.BindAddr), Port: m.config.BindPort}
	udp.WriteTo(buf.Bytes(), addr)

	// Wait for response
	go func() {
		time.Sleep(time.Second)
		panic("timeout")
	}()

	in := make([]byte, 1500)
	n, _, err := udp.ReadFrom(in)
	if err != nil {
		t.Fatalf("unexpected err %s", err)
	}
	in = in[0:n]

	msgType := messageType(in[0])
	if msgType != compoundMsg {
		t.Fatalf("bad response %v", in)
	}

	// get the parts
	trunc, parts, err := decodeCompoundMessage(in[1:])
	if trunc != 0 {
		t.Fatalf("unexpected truncation")
	}
	if len(parts) != 2 {
		t.Fatalf("unexpected parts %v", parts)
	}
	if err != nil {
		t.Fatalf("unexpected err %s", err)
	}

	var ack ackResp
	if err := decode(parts[0][1:], &ack); err != nil {
		t.Fatalf("unexpected err %s", err)
	}

	if ack.SeqNo != 42 {
		t.Fatalf("bad sequence no")
	}

	var aliveout alive
	if err := decode(parts[1][1:], &aliveout); err != nil {
		t.Fatalf("unexpected err %s", err)
	}

	if aliveout.Node != "rand" || aliveout.Incarnation != 10 {
		t.Fatalf("bad mesg")
	}
}