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
}
func NewLoadBalancer(port int, monitorhostport string) *LoadBalancer {
	lb := new(LoadBalancer)
	lsplog.Vlogf(1, "[NewLoadBalancer] Dialing master... %v", monitorhostport)
	// connexion to monitor
	// server to communicate with workers
	lb.server, _ = lsp12.NewLspServer(port+10, &lsp12.LspParams{5, 2000})
	lb.monitor, _ = rpc.DialHTTP("tcp", monitorhostport)
	name, _ := os.Hostname()
	addrs, _ := net.LookupHost(name)
	lb.myAddress = addrs[0]
	args := &commproto.RegisterLoadBalancerArgs{fmt.Sprintf("%s:%v", addrs[0], port)}
	var reply commproto.RegisterLoadBalancerReply
	lb.monitor.Call("MonitorRPC.RegisterLoadBalancer", args, &reply)
	lsplog.Vlogf(1, "[NewLoadBalancer] Completed registration %s %+v", reply.Buddy, reply.LoadBalancersHostPort)
	lb.buddy = reply.Buddy
	lb.loadBalancers = reply.LoadBalancersHostPort
	// get workers
	lb.workers = reply.Workers
	lb.numberOfWorkers = len(lb.workers)
	lsplog.Vlogf(2, "[LoadBalancer] Establishing conn to workers")
	// establish RPC connexion load balancers
	lb.workersRPC = make(map[string]*rpc.Client)
	for i := 0; i < len(lb.workers); i++ {
		lb.workersRPC[lb.workers[i]], _ = rpc.DialHTTP("tcp", lb.workers[i])
	}
	lsplog.Vlogf(2, "[LoadBalancer] Establishing conn to LB")
	// establish RPC connexion with workers
	//numLbs := len(lb.loadBalancers)
	lb.LbsRPC = make(map[string]*rpc.Client)
	//for i := 0; i < numLbs; i ++ {
	//lb.LbsRPC[lb.loadBalancers[i]], _ = rpc.DialHTTP("tcp", lb.loadBalancers[i])
	//}
	lsplog.Vlogf(2, "[LoadBalancer] Established connections")
	lb.clientDict = make(map[uint16]*commproto.ClientS)
	lb.replicatedInformation = make(map[string]int)
	//lsplog.Vlogf(1, "[LoadBalancer] Received buddy: %s loadBalancers: %s", reply.Buddy, lb.loadBalancers)

	// connexion to switch
	addr, errResolve := lspnet.ResolveUDPAddr("udp", fmt.Sprintf(":%d", port))
	if errResolve != nil {
		return nil
	}
	connexion, errDial := lspnet.ListenUDP("udp", addr)
	if errDial != nil {
		return nil
	}
	lb.connSwitch = connexion
	lsplog.Vlogf(1, "[LoadBalancer] Received buddy: %s loadBalancers: %s", reply.Buddy, lb.loadBalancers)

	go lb.runLoadBalancer()
	go lb.buddyHeartbeat()
	return lb
}
func NewSwitch(port int) *Switch {
	sw := new(Switch)
	sw.connId = 1
	sw.registered = make(chan bool, 1)
	addr, errResolve := lspnet.ResolveUDPAddr("udp", fmt.Sprintf(":%d", port))
	if errResolve != nil {
		return nil
	}
	connexion, errListen := lspnet.ListenUDP("udp", addr)
	if errListen != nil {
		return nil
	}
	sw.srv = connexion
	go runServer(sw)
	return sw
}
func iNewLspServer(port int, params *LspParams) (*LspServer, error) {
	server := new(LspServer)
	server.ClientDict = make(map[uint16]*iClient)
	server.Wchan = make(chan int, 1)
	server.WBchan = make(chan *LspMessage, 1)
	server.Nchan = make(chan *LspMessage, 1)
	server.Echan = make(chan int, 1)
	server.EchanBack = make(chan int, 1)
	server.CloseChan = make(chan int, 1)
	server.CloseChanEpoch = make(chan int, 1)
	server.CloseNetworkChan = make(chan int, 1)
	server.eventHandClosedChan = make(chan int, 1)
	server.CloseConnChan = make(chan uint16, 1)
	server.Rchan = make(chan int)
	server.RBchan = make(chan *LspMessage)
	server.Addrchan = make(chan *lspnet.UDPAddr, 1)
	server.writeEnded = make(chan int, 1)
	server.errChan = make(chan error, 1)
	server.exitEpochHandler = make(chan int, 1)
	server.continueEpochHandler = make(chan int, 1)
	server.connId = 1
	server.NbWrite = 0
	server.readList = new(list.List)
	if params == nil {
		server.params = &LspParams{5, 2000}
	} else {
		server.params = params
	}
	addr, errResolve := lspnet.ResolveUDPAddr("udp", fmt.Sprintf(":%d", port))
	if errResolve != nil {
		return nil, errResolve
	}
	connexion, errListen := lspnet.ListenUDP("udp", addr)
	if errListen != nil {
		return nil, errListen
	}
	server.conn = connexion
	server.running = true
	server.epochCount = 0
	server.eventHandClosed = false
	go NetworkHandlerServer(server)
	go EventHandlerServer(server)
	go EpochHandlerServer(server)
	return server, nil
}