示例#1
0
func iNewLspServer(port int, params *LspParams) (*LspServer, error) {
	srv := new(LspServer)
	srv.nextId = 1
	if params == nil {
		// Insert default parameters
		params = &LspParams{5, 2000}
	}
	srv.params = params
	hostport := fmt.Sprintf(":%v", port)
	addr, err := lspnet.ResolveUDPAddr("udp", hostport)
	if lsplog.CheckReport(1, err) {
		return nil, err
	}
	srv.udpConn, err = lspnet.ListenUDP("udp", addr)
	if lsplog.CheckReport(1, err) {
		return nil, err
	}
	srv.readBuf = NewBuf()
	// Need enough room to recycle close messages
	srv.appReadChan = make(LspMessageChan, 1)
	srv.appWriteChan = make(LspMessageChan)
	srv.netInChan = make(networkChan)
	srv.epochChan = make(chan int)
	srv.connById = make(map[uint16]*lspConn)
	srv.connByAddr = make(map[string]*lspConn)
	srv.closeReplyChan = make(chan error, 1)
	srv.closeAllReplyChan = make(chan error, 1)
	srv.writeReplyChan = make(chan error, 1)

	go srv.serverLoop()
	go srv.udpReader()
	go epochTrigger(srv.params.EpochMilliseconds, srv.epochChan, &srv.stopGlobalNetworkFlag)
	return srv, nil
}
示例#2
0
// Shut down all network activity
func (srv *LspServer) stopGlobalNetwork() {
	srv.stopGlobalNetworkFlag = true
	err := srv.udpConn.Close()
	if lsplog.CheckReport(4, err) {
		lsplog.Vlogf(6, "Server Continuing\n")
	}
}
示例#3
0
// Write message to UDP connection.  Address specified by con
func (srv *LspServer) udpWrite(con *lspConn, msg *LspMessage) {
	b := msg.genPacket()
	_, err := srv.udpConn.WriteToUDP(b, con.addr)
	if lsplog.CheckReport(6, err) {
		srv.Vlogf(6, "Write failed\n")
	}
}
示例#4
0
// Shutting down network communications
func (cli *LspClient) stopNetwork() {
	cli.lspConn.stopNetworkFlag = true
	err := cli.udpConn.Close()
	if lsplog.CheckReport(4, err) {
		lsplog.Vlogf(6, "Client Continuing\n")
	}
}
示例#5
0
// Write message to UDP connection.  Address already registered with connection
func (cli *LspClient) udpWrite(msg *LspMessage) {
	b := msg.genPacket()
	_, err := cli.udpConn.Write(b)
	if lsplog.CheckReport(6, err) {
		cli.Vlogf(6, "Write failed\n")
	}
}
示例#6
0
// Goroutine that reads messages from UDP connection and writes to message channel
func (cli *LspClient) udpReader() {
	udpConn := cli.udpConn
	mc := cli.netInChan
	var buffer [1500]byte
	for !cli.lspConn.stopNetworkFlag {
		n, _, err := udpConn.ReadFromUDP(buffer[0:])
		if lsplog.CheckReport(1, err) {
			cli.Vlogf(6, "Client continuing\n")
			continue
		}
		m, merr := extractMessage(buffer[0:n])
		if lsplog.CheckReport(1, merr) {
			cli.Vlogf(6, "Client continuing\n")
			continue
		}
		mc <- m
	}
}
示例#7
0
// Goroutine that reads messages from UDP connection and writes to message channel
func (srv *LspServer) udpReader() {
	udpConn := srv.udpConn
	netc := srv.netInChan
	var buffer [1500]byte
	for !srv.stopGlobalNetworkFlag {
		n, addr, err := udpConn.ReadFromUDP(buffer[0:])
		if lsplog.CheckReport(1, err) {
			srv.Vlogf(5, "Server continuing\n")
			continue
		}
		m, merr := extractMessage(buffer[0:n])
		if lsplog.CheckReport(1, merr) {
			srv.Vlogf(6, "Server continuing\n")
			continue
		}
		srv.Vlogf(5, "Received message %s\n", m)
		d := &networkData{m, addr}
		netc <- d
	}
}
示例#8
0
func iNewLspClient(hostport string, params *LspParams) (*LspClient, error) {
	cli := new(LspClient)
	if params == nil {
		// Insert default parameters
		params = &LspParams{5, 2000}
	}
	cli.params = params
	addr, err := lspnet.ResolveUDPAddr("udp", hostport)
	if lsplog.CheckReport(1, err) {
		return nil, err
	}
	cli.lspConn = newConn(addr, 0, 0)
	// Client's first received message will be data message.
	cli.lspConn.nextRecvSeqNum = NextSeqNum(0)
	cli.udpConn, err = lspnet.DialUDP("udp", nil, addr)
	if lsplog.CheckReport(1, err) {
		return nil, err
	}
	// Need enough room to recycle close messages at end
	cli.appReadChan = make(LspMessageChan, 2)
	cli.readBuf = NewBuf()
	cli.appWriteChan = make(LspMessageChan, 1)
	cli.netInChan = make(LspMessageChan, 1)
	cli.epochChan = make(chan int)
	cli.closeReplyChan = make(chan error, 2)
	cli.writeReplyChan = make(chan error, 2)

	go cli.clientLoop()
	go cli.udpReader()
	go epochTrigger(cli.params.EpochMilliseconds, cli.epochChan, &cli.lspConn.stopNetworkFlag)
	// Send connection request to server
	nm := GenConnectMessage()
	cli.udpWrite(nm)
	cli.lspConn.pendingMsg = nm
	cli.lspConn.nextSendSeqNum = NextSeqNum(0)
	cm := <-cli.appReadChan
	if cm.Type == MsgCONNECT {
		return cli, nil
	}
	return nil, lsplog.MakeErr("Connection failed")
}
示例#9
0
func (srv *LspServer) networkHandler() {
	lsplog.Vlogf(3, "[Server] Started the network handler")
	for { // Should loop only if the connection is still on.
		lsplog.Vlogf(6, "[Server] Going to read a packet")
		m, addr, err := srv.readPacket()
		if err != nil {
			lsplog.CheckReport(3, err)
			lsplog.Vlogf(6, "[Server] Ignoring this packet")
			continue
		}
		go srv.packetHandler(m, addr)
	}
}
func main() {
	var ihelp *bool = flag.Bool("h", false, "Show help information")
	var iport *int = flag.Int("p", 6666, "Port number")
	var ihost *string = flag.String("H", "localhost", "Host address")
	var iverb *int = flag.Int("v", 1, "Verbosity (0-6)")
	var irdrop *int = flag.Int("r", 0, "Network read packet drop percentage")
	var iwdrop *int = flag.Int("w", 0, "Network write packet drop percentage")
	var elim *int = flag.Int("k", 5, "Epoch limit")
	var ems *int = flag.Int("d", 2000, "Epoch duration (millisecconds)")
	flag.Parse()
	if *ihelp {
		flag.Usage()
		os.Exit(0)
	}
	if flag.NArg() > 0 {
		// Look for host:port on command line
		ok := true
		fields := strings.Split(flag.Arg(0), ":")
		ok = ok && len(fields) == 2
		if ok {
			*ihost = fields[0]
			n, err := fmt.Sscanf(fields[1], "%d", iport)
			ok = ok && n == 1 && err == nil
		}
		if !ok {
			flag.Usage()
			os.Exit(0)
		}
	}
	params := &lsp12.LspParams{*elim, *ems}

	lsplog.SetVerbose(*iverb)
	lspnet.SetReadDropPercent(*irdrop)
	lspnet.SetWriteDropPercent(*iwdrop)
	hostport := fmt.Sprintf("%s:%v", *ihost, *iport)
	fmt.Printf("Connecting to server at %s\n", hostport)
	cli, err := lsp12.NewLspClient(hostport, params)
	if err != nil {
		fmt.Printf("... failed.  Error message %s\n", err.Error())
	}
	if lsplog.CheckReport(1, err) {
		return
	}
	runclient(cli)
}
示例#11
0
func (cli *LspClient) readPacket() (m *LspMessage, addr *lspnet.UDPAddr, e error) {
	b := make([]byte, 1000)
	n, addr, err := cli.udpConn.ReadFromUDP(b)
	if addr == nil || n == 0 {
		lsplog.Vlogf(3, "[Client] Recieved a terminating packet.")
		return nil, addr, lsplog.ConnectionClosed()
	} else {
		lsplog.Vlogf(5, "[Client] Recieved a packet from %s:%d", addr.IP.String(), addr.Port)
	}
	if err != nil {
		lsplog.CheckFatal(err)
		return nil, nil, err
	}
	recieved := CreateEmptyPacket()
	err = json.Unmarshal(b[0:n], recieved)
	if err != nil {
		lsplog.CheckReport(3, err)
		return nil, addr, err
	}
	lsplog.Vlogf(6, "[Client] Recieved packet %+v", recieved)
	return recieved, addr, err
}
示例#12
0
func (srv *LspServer) readPacket() (m *LspMessage, addr *lspnet.UDPAddr, e error) {
	b := make([]byte, 1000)
	n, addr, err := srv.udpConn.ReadFromUDP(b)
	if addr == nil {
		lsplog.Vlogf(3, "[Server] Recieved a terminating packet.")
		return nil, addr, lsplog.ConnectionClosed()
	} else {
		lsplog.Vlogf(4, "[Server] Recieved a packet from %s:%d with length %d", addr.IP.String(), addr.Port, n)
	}
	if err != nil {
		lsplog.Vlogf(3, "[Server] Error occured while reading from UDP.")
		lsplog.CheckFatal(err)
		return nil, nil, err
	}
	recieved := CreateEmptyPacket()
	err = json.Unmarshal(b[0:n], recieved)
	if err != nil {
		lsplog.Vlogf(6, "[Server] Error while unmarshalling %X", b)
		lsplog.CheckReport(4, err)
		return nil, addr, err
	}
	lsplog.Vlogf(5, "[Server] Recieved packet %+v", recieved)
	return recieved, addr, err
}
示例#13
0
func (cli *LspClient) networkHandler() {
	lsplog.Vlogf(3, "[Client] Started the network handler")
	for { // Should loop only if the connection is still on.
		lsplog.Vlogf(6, "[Client] Going to read a packet")
		m, addr, err := cli.readPacket()
		if err != nil && addr == nil { // Found out that whenever a connection is closed, the address becomes nil.
			lsplog.CheckReport(3, err)
			lsplog.Vlogf(3, "[Client] Terminating network handler.")
			break
		}

		if err != nil {
			lsplog.CheckReport(3, err)
			continue
		}

		if !bytes.Equal(addr.IP, cli.udpAddr.IP) {
			lsplog.Vlogf(5, "[Client] Address of packet is unknown. Ignoring packet.")
			continue
		}

		lsplog.Vlogf(5, "[Client] Packet recieved is valid.")
		if IsConnectionAck(m) && !cli.connectionAlive {
			lsplog.Vlogf(5, "[Client] Connection acknowledged.")
			cli.connId = m.ConnId
			cli.makeConnectionAlive()
		} else if IsDataPacket(m) {
			lsplog.Vlogf(4, "[Client] Recieved a data packet from server.")
			if m.ConnId == cli.connId {
				lsplog.Vlogf(6, "[Client] Data packet belongs to this client.")
				if m.SeqNum == cli.serverSeqNum {
					lsplog.Vlogf(5, "[Client] Data packet has an expected sequence.")
					cli.read.Insert(m.Payload)
					cli.serverSeqNum = (cli.serverSeqNum + 1) % math.MaxInt8
					lsplog.Vlogf(5, "[Client] Server sequence number became (%d).", cli.serverSeqNum)
					dataAck := CreateDataAck(cli.connId, m.SeqNum)
					cli.lastAck = dataAck
					cli.lspSend(dataAck)
				} else {
					lsplog.Vlogf(5, "[Client] Message sequence number (%d) in packet is not expected (%d).", m.SeqNum, cli.serverSeqNum)
				}
			} else {
				lsplog.Vlogf(4, "[Client] connId (%d) in packet is not the same as the client connId (%d).", m.ConnId, cli.connId)
			}
		} else {
			lsplog.Vlogf(4, "[Client] Recieved an acknowledgment packet from server.")
			<-cli.sentLocker
			deletedElements := list.New()
			for e := cli.sent.Front(); e != nil; e = e.Next() {
				sentMessage := e.Value.(*LspMessage)
				if sentMessage.SeqNum <= m.SeqNum {
					deletedElements.PushBack(e)
				}
			}
			for e := deletedElements.Front(); e != nil; e = e.Next() {
				cli.sent.Remove(e.Value.(*list.Element))
			}
			cli.sentLocker <- 1
		}
		cli.resetEpochCounter()
	}
	lsplog.Vlogf(3, "[Client] Terminated network handler")
}