Beispiel #1
0
func startUDP(sink chan Pkt) {
	bind, err := net.ResolveUDPAddr("udp", *bindAddr)
	ready := make(chan struct{})
	if err != nil {
		log.Fatalln("Can not resolve bind address:", err)
	}
	lconn, err := net.ListenUDP("udp", bind)
	if err != nil {
		log.Fatalln("Can not listen on UDP:", err)
	}
	log.Println("Listening on UDP", *bindAddr)
	go func() {
		buf := make([]byte, govpn.MTU)
		var n int
		var raddr *net.UDPAddr
		var err error
		for {
			<-ready
			lconn.SetReadDeadline(time.Now().Add(time.Second))
			n, raddr, err = lconn.ReadFromUDP(buf)
			if err != nil {
				sink <- Pkt{ready: ready}
				continue
			}
			sink <- Pkt{
				raddr.String(),
				UDPSender{lconn, raddr},
				buf[:n],
				ready,
			}
		}
	}()
	ready <- struct{}{}
}
Beispiel #2
0
func (proxy *UDPProxy) replyLoop(proxyConn *net.UDPConn, clientAddr *net.UDPAddr, clientKey *connTrackKey) {
	defer func() {
		proxy.connTrackLock.Lock()
		delete(proxy.connTrackTable, *clientKey)
		proxy.connTrackLock.Unlock()
		utils.Debugf("Done proxying between udp/%v and udp/%v", clientAddr.String(), proxy.backendAddr.String())
		proxyConn.Close()
	}()

	readBuf := make([]byte, UDPBufSize)
	for {
		proxyConn.SetReadDeadline(time.Now().Add(UDPConnTrackTimeout))
	again:
		read, err := proxyConn.Read(readBuf)
		if err != nil {
			if err, ok := err.(*net.OpError); ok && err.Err == syscall.ECONNREFUSED {
				// This will happen if the last write failed
				// (e.g: nothing is actually listening on the
				// proxied port on the container), ignore it
				// and continue until UDPConnTrackTimeout
				// expires:
				goto again
			}
			return
		}
		for i := 0; i != read; {
			written, err := proxy.listener.WriteToUDP(readBuf[i:read], clientAddr)
			if err != nil {
				return
			}
			i += written
			utils.Debugf("Forwarded %v/%v bytes to udp/%v", i, read, clientAddr.String())
		}
	}
}
Beispiel #3
0
func AttemptOne(server *net.UDPAddr, ch chan bool) {
	conn, err := net.Dial("udp", server.String())
	res := false
	defer func() {
		ch <- res
	}()
	if err != nil {
		return
	}
	defer conn.Close()
	if err = conn.SetDeadline(time.Now().Add(2 * time.Second)); err != nil {
		return
	}

	request := []byte{
		0, 1, // Binding request
		0, 0, // Message length
		0x21, 0x12, 0xa4, 0x42, // magic
		1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} // TID

	if n, err := conn.Write(request); err != nil || n != len(request) {
		return
	}

	buf := make([]byte, 1024)
	n, err := conn.Read(buf)
	res = (n > 0 && err == nil)
	return
}
Beispiel #4
0
func (handler *VMessInboundHandler) handlePacket(conn *net.UDPConn, request *protocol.VMessRequest, packet v2net.Packet, clientAddr *net.UDPAddr) {
	ray := handler.vPoint.DispatchToOutbound(packet)
	close(ray.InboundInput())

	responseKey := md5.Sum(request.RequestKey)
	responseIV := md5.Sum(request.RequestIV)

	buffer := alloc.NewBuffer().Clear()
	defer buffer.Release()

	responseWriter, err := v2io.NewAesEncryptWriter(responseKey[:], responseIV[:], buffer)
	if err != nil {
		log.Error("VMessIn: Failed to create encrypt writer: %v", err)
		return
	}
	responseWriter.Write(request.ResponseHeader)

	hasData := false

	if data, ok := <-ray.InboundOutput(); ok {
		hasData = true
		responseWriter.Write(data.Value)
		data.Release()
	}

	if hasData {
		conn.WriteToUDP(buffer.Value, clientAddr)
		log.Info("VMessIn sending %d bytes to %s", buffer.Len(), clientAddr.String())
	}
}
Beispiel #5
0
func isValidNonce(clientUDPAddr *net.UDPAddr, nonceFromClient int64) bool {
	clientUDPIpPort := clientUDPAddr.String()
	state.nonceMap.RLock()
	isValid := state.nonceMap.Map[clientUDPIpPort] == nonceFromClient
	state.nonceMap.RUnlock()
	return isValid
}
Beispiel #6
0
/*
	Starts a UDP listener which will forward received data back to the application using
	the supplied channel.  The listener ID is returned along with a boolean indication
	of success (true) or failure. The uid is the user created session id string that is
	used to send buffers that are not related to a session_data struct.
*/
func (this *Cmgr) Listen_udp(port int, data2usr chan *Sess_data) (uid string, err error) {
	var addr net.UDPAddr

	uid = ""
	addr.IP = net.IPv4(0, 0, 0, 0)
	addr.Port = port
	uconn, err := net.ListenUDP("udp", &addr)
	if err != nil {
		err = fmt.Errorf("unable to create a udp listener on port: %d; %s", port, err)
		return
	}

	uid = fmt.Sprintf("u%d", this.ucount) // successful bind to port
	this.ucount += 1

	cp := new(connection)
	cp.conn = nil
	cp.uconn = uconn
	cp.data2usr = data2usr  // session data written to the channel
	cp.id = uid             // user assigned session id
	this.clist[uid] = cp    // hash for write to session
	go this.conn_reader(cp) // start reader; will discard if data2usr is nil

	this.clist[uid] = cp
	return
}
Beispiel #7
0
func (listener *Listener) newUDPSession(remote *net.UDPAddr) (*UDPSession, bool) {

	remoteAddrStr := remote.String()
	listener.Lock()
	if sess, ok := listener.remoteAddrs[remoteAddrStr]; ok == true {
		listener.Unlock()
		return sess, true
	}
	listener.Unlock()

	var err error
	var local *net.UDPConn
	if local, err = net.ListenUDP("udp", &net.UDPAddr{}); err != nil {
		//log.Println(err)
		return nil, false
	}
	localAddr := local.LocalAddr().(*net.UDPAddr)

	sess := newUDPSession(listener, remote, local, localAddr)

	listener.Lock()
	listener.remoteAddrs[remoteAddrStr] = sess
	listener.Unlock()

	return sess, false
}
Beispiel #8
0
func Pipeloop(ss *UDPConn, srcaddr *net.UDPAddr, remote UDP) {
	buf := udpBuf.Get()
	defer udpBuf.Put(buf)
	defer nl.Delete(srcaddr.String())
	for {
		remote.SetReadDeadline(time.Now().Add(ss.timeout))
		n, raddr, err := remote.ReadFrom(buf)
		if err != nil {
			if ne, ok := err.(*net.OpError); ok && (ne.Err == syscall.EMFILE || ne.Err == syscall.ENFILE) {
				// log too many open file error
				// EMFILE is process reaches open file limits, ENFILE is system limit
				fmt.Println("[udp]read error:", err)
			} else if ne.Err.Error() == "use of closed network connection" {
				fmt.Println("[udp]Connection Closing:", remote.LocalAddr())
			} else {
				fmt.Println("[udp]error reading from:", remote.LocalAddr(), err)
			}
			return
		}
		// need improvement here
		if N, ok := ReqList[raddr.String()]; ok {
			go ss.WriteToUDP(append(N.Req[:N.ReqLen], buf[:n]...), srcaddr)
		} else {
			header, hlen := ParseHeader(raddr)
			go ss.WriteToUDP(append(header[:hlen], buf[:n]...), srcaddr)
		}
	}
}
Beispiel #9
0
// Caller should have lock on UdpSession
func (s *UdpSession) Update(addr *net.UDPAddr) error {
	if s.Addr.String() != addr.String() {
		s.Addr = addr
	}
	s.LastHeartbeat = time.Now()
	return nil
}
Beispiel #10
0
//Generate new nonce for udpAddr and add to nonceMap
func generateNewNonce(udpAddr *net.UDPAddr, nonceMap clientServerUtils.ConcurrentMap) int64 {
	nonce := rand.Int63()
	nonceMap.Lock()
	nonceMap.Map[udpAddr.String()] = nonce
	nonceMap.Unlock()
	return nonce
}
Beispiel #11
0
func (nl *NATlist) Get(srcaddr *net.UDPAddr, ss *UDPConn) (c *CachedUDPConn, ok bool, err error) {
	nl.Lock()
	defer nl.Unlock()
	index := srcaddr.String()
	_, ok = nl.Conns[index]
	if !ok {
		//NAT not exists or expired
		nl.AliveConns += 1
		delete(nl.Conns, index)
		ok = false
		//full cone
		conn, err := net.ListenUDP("udp", &net.UDPAddr{
			IP:   net.IPv6zero,
			Port: 0,
		})
		if err != nil {
			return nil, false, err
		}
		nl.Conns[index] = NewCachedUDPConn(conn)
		c, _ = nl.Conns[index]
		c.SetTimer(index)
		go Pipeloop(ss, srcaddr, c)
	} else {
		//NAT exists
		c, _ = nl.Conns[index]
		c.Refresh()
	}
	err = nil
	return
}
Beispiel #12
0
func (c *udpConn) WriteToUDP(b []byte, a *net.UDPAddr) (int, error) {
	if atomic.LoadUint32(&c.closed) != 0 {
		return 0, fmt.Errorf("connection is closed")
	}

	c.inet.mutex.Lock()
	defer c.inet.mutex.Unlock()
	dst := c.inet.listeners[a.String()]
	if dst == nil {
		return len(b), nil // drop packet
	}

	b2 := make([]byte, len(b))
	copy(b2, b)

	select {
	case dst.rxChan <- udpPacket{
		Data:        b2,
		Source:      c.addr,
		Destination: *a,
	}:
	default:
		// rx buffer full, drop packet
	}

	return len(b), nil
}
Beispiel #13
0
// Handle a new client read or write request.
func (s *Server) HandleClient(addr *net.UDPAddr, req pkt.Packet) {
	s.Logger.Debug("Handle Client!")

	reqpkt, ok := req.(*pkt.ReqPacket)
	if !ok {
		s.Logger.Error("Invalid packet type for new connection!")
		return
	}
	// Re-resolve for verification
	clientaddr, err := net.ResolveUDPAddr("udp", addr.String())
	if err != nil {
		s.Logger.Error("Error: %s", err)
		return
	}

	switch reqpkt.GetType() {
	case pkt.RRQ:
		err := s.HandleReadReq(reqpkt, clientaddr)
		if err != nil {
			s.Logger.Error("read request finished, with error:", err)
		}
	case pkt.WRQ:
		err := s.HandleWriteReq(reqpkt, clientaddr)
		if err != nil {
			s.Logger.Error("write request finished, with error:", err)
		}
	default:
		s.Logger.Error("Invalid Packet Type!")
	}
}
Beispiel #14
0
func (d *DHT) ping(queryNode *net.UDPAddr) (nodeId []byte) {

	// Prepare request.
	ch := make(chan interface{})
	reqId := d.getRequestId()
	d.requests[queryNode.String()+string(reqId)] = &Request{ch, time.Now()}

	// Send.
	buf := []byte("d1:ad2:id20:")
	buf = append(buf, d.self.id...)
	buf = append(buf, []byte("e1:q4:ping1:t2:")...)
	buf = append(buf, reqId...)
	buf = append(buf, []byte("1:y1:qe")...)

	d.conn.WriteTo(buf, queryNode)

	// Wait for response.
	res := <-ch

	id, ok := res.(bencode.Dict)["r"].(bencode.Dict)["id"].(string)
	if !ok {
		return nil
	}

	return []byte(id)
}
Beispiel #15
0
// It's not found because we are using a different thing
func getUserAlias(who *net.UDPAddr) (string, error) {
	usr, ok := connections[who.String()]
	if !ok {
		return "", errors.New("Your user wasn't found. Please login first")
	}
	return usr.Alias, nil
}
Beispiel #16
0
func respondWithFallback(raw []uint8, clientMsg *dns.Msg, clientQuestion dns.Question, proxy *net.UDPAddr) {
	LOG.Println("fallback:", clientQuestion, proxy)
	conn, err := net.Dial("udp", proxy.String())
	if err != nil {
		LOG.Fatalln(err)
	}

	conn.Write(raw)

	buffer := make([]byte, 1<<15)
	size, err := conn.Read(buffer)
	if err != nil {
		LOG.Fatalln(err, proxy)
	}

	msg := &dns.Msg{}
	msg.Unpack(buffer[0:size])

	LOG.Println(msg)

	for _, answer := range msg.Answer {
		clientMsg.Answer = append(clientMsg.Answer, answer)
	}

	clientMsg.Rcode = msg.Rcode
	clientMsg.Response = msg.Response
	clientMsg.Authoritative = msg.Authoritative
	clientMsg.Recursion_desired = msg.Recursion_desired
	clientMsg.Recursion_available = msg.Recursion_available
}
Beispiel #17
0
func main() {
	listen := flag.String("addr", ":2055", "Listen address")
	flag.Parse()

	var addr *net.UDPAddr
	var err error
	if addr, err = net.ResolveUDPAddr("udp", *listen); err != nil {
		log.Fatal(err)
	}

	var server *net.UDPConn
	if server, err = net.ListenUDP("udp", addr); err != nil {
		log.Fatal(err)
	}

	decoders := make(map[string]*netflow.Decoder)
	for {
		buf := make([]byte, 8192)
		var remote *net.UDPAddr
		if _, remote, err = server.ReadFromUDP(buf); err != nil {
			log.Printf("error reading from %s: %v\n", remote, err)
			continue
		}

		log.Printf("received %d bytes from %s\n", len(buf), remote)

		d, found := decoders[remote.String()]
		if !found {
			s := session.New()
			d = netflow.NewDecoder(s)
			decoders[remote.String()] = d
		}

		m, err := d.Read(bytes.NewBuffer(buf))
		if err != nil {
			log.Println("decoder error:", err)
			continue
		}

		switch p := m.(type) {
		case *netflow1.Packet:
			netflow1.Dump(p)

		case *netflow5.Packet:
			netflow5.Dump(p)

		case *netflow6.Packet:
			netflow6.Dump(p)

		case *netflow7.Packet:
			netflow7.Dump(p)

		case *netflow9.Packet:
			netflow9.Dump(p)

		case *ipfix.Message:
			ipfix.Dump(p)
		}
	}
}
func (nl *NATlist) Get(srcaddr, dstaddr *net.UDPAddr, cn *UDPConn, header []byte) (c *CachedUDPConn, ok bool, err error) {
	nl.Lock()
	defer nl.Unlock()
	index := srcaddr.String() + dstaddr.String()
	_, ok = nl.Conns[index]
	if !ok || nl.Conns[index].Expired {
		//NAT not exists or expired
		delete(nl.Conns, index)
		ok = false
		conn, err := net.DialUDP("udp", nil, dstaddr)
		if err != nil {
			return nil, false, err
		}
		nl.Conns[index] = NewCachedUDPConn(conn)
		c, _ = nl.Conns[index]
		c.SetTimer()
		go Pipeloop(cn, srcaddr, c, header)
	} else {
		//NAT exists
		c, _ = nl.Conns[index]
		c.Refresh()
	}
	err = nil
	return
}
Beispiel #19
0
func (handler *VMessInboundHandler) handlePacket(conn *net.UDPConn, request *protocol.VMessRequest, packet v2net.Packet, clientAddr *net.UDPAddr) {
	ray := handler.vPoint.DispatchToOutbound(packet)
	close(ray.InboundInput())

	responseKey := md5.Sum(request.RequestKey[:])
	responseIV := md5.Sum(request.RequestIV[:])

	buffer := bytes.NewBuffer(make([]byte, 0, bufferSize))

	response := protocol.NewVMessResponse(request)
	responseWriter, err := v2io.NewAesEncryptWriter(responseKey[:], responseIV[:], buffer)
	if err != nil {
		log.Error("VMessIn: Failed to create encrypt writer: %v", err)
		return
	}
	responseWriter.Write(response[:])

	hasData := false

	if data, ok := <-ray.InboundOutput(); ok {
		hasData = true
		responseWriter.Write(data)
	}

	if hasData {
		conn.WriteToUDP(buffer.Bytes(), clientAddr)
		log.Info("VMessIn sending %d bytes to %s", len(buffer.Bytes()), clientAddr.String())
	}
}
Beispiel #20
0
// ProcessPacket decodes and processes a received UDP packet, sending responses
// and forwarding the packet on to other clients as appropriate.
func (server *IPXServer) ProcessPacket(packet []byte, addr *net.UDPAddr) {
	var header IPXHeader
	if !header.Decode(packet) {
		return
	}

	if header.IsRegistrationPacket() {
		server.NewClient(&header, addr)
		return
	}

	srcClient, ok := server.clients[addr.String()]
	if !ok {
		return
	}

	// Clients can only send from their own address.
	if header.src.addr != srcClient.ipxAddr {
		return
	}

	srcClient.lastReceiveTime = time.Now()

	if header.IsBroadcast() {
		server.ForwardBroadcastPacket(&header, packet)
	} else {
		server.ForwardPacket(&header, packet)
	}
}
Beispiel #21
0
func OpenDoor(raddr *net.UDPAddr) {
	OpenCmd, err := RenderTemplate(cfg.OpenCmd, raddr)
	if err != nil {
		fmt.Printf("open template Error: %s.\n", err.Error())
		return
	}

	CloseCmd, err := RenderTemplate(cfg.CloseCmd, raddr)
	if err != nil {
		fmt.Printf("close template Error: %s.\n", err.Error())
		return
	}

	fmt.Printf("open door for %s.\n", raddr.String())
	err = RunCmd(OpenCmd)
	if err != nil {
		fmt.Printf("open exec Error: %s.\n", err.Error())
		return
	}

	go func() {
		time.Sleep(time.Duration(cfg.Interval) * time.Second)

		fmt.Printf("close door for %s.\n", raddr.String())
		err := RunCmd(CloseCmd)
		if err != nil {
			fmt.Printf("close exec Error: %s.\n", err.Error())
			return
		}
	}()
}
Beispiel #22
0
func (nl *NATlist) Get(srcaddr *net.UDPAddr, ss *UDPConn) (c *CachedUDPConn, ok bool, err error) {
	nl.Lock()
	defer nl.Unlock()
	index := srcaddr.String()
	_, ok = nl.Conns[index]
	if !ok {
		//NAT not exists or expired
		Debug.Printf("new udp conn %v<-->%v\n", srcaddr, ss.LocalAddr())
		nl.AliveConns += 1
		ok = false
		//full cone
		addr, _ := net.ResolveUDPAddr("udp", ":0")
		conn, err := net.ListenUDP("udp", addr)
		if err != nil {
			return nil, false, err
		}
		c = NewCachedUDPConn(conn)
		nl.Conns[index] = c
		c.SetTimer(index)
		go Pipeloop(ss, srcaddr, c)
	} else {
		//NAT exists
		c, _ = nl.Conns[index]
		c.Refresh()
	}
	err = nil
	return
}
Beispiel #23
0
func (nDB *NetworkDB) reconnectNode() {
	nDB.RLock()
	if len(nDB.failedNodes) == 0 {
		nDB.RUnlock()
		return
	}

	nodes := make([]*node, 0, len(nDB.failedNodes))
	for _, n := range nDB.failedNodes {
		nodes = append(nodes, n)
	}
	nDB.RUnlock()

	node := nodes[randomOffset(len(nodes))]
	addr := net.UDPAddr{IP: node.Addr, Port: int(node.Port)}

	if _, err := nDB.memberlist.Join([]string{addr.String()}); err != nil {
		return
	}

	if err := nDB.sendNodeEvent(NodeEventTypeJoin); err != nil {
		logrus.Errorf("failed to send node join during reconnect: %v", err)
		return
	}

	// Update all the local table state to a new time to
	// force update on the node we are trying to rejoin, just in
	// case that node has these in deleting state still. This is
	// facilitate fast convergence after recovering from a gossip
	// failure.
	nDB.updateLocalTableTime()

	logrus.Debugf("Initiating bulk sync with node %s after reconnect", node.Name)
	nDB.bulkSync([]string{node.Name}, true)
}
Beispiel #24
0
func Pipeloop(ss *UDPConn, srcaddr *net.UDPAddr, remote UDP) {
	buf := pool.Get().([]byte)
	defer pool.Put(buf)
	defer nl.Delete(srcaddr.String())
	for {
		n, raddr, err := remote.ReadFrom(buf)
		if err != nil {
			if ne, ok := err.(*net.OpError); ok && (ne.Err == syscall.EMFILE || ne.Err == syscall.ENFILE) {
				// log too many open file error
				// EMFILE is process reaches open file limits, ENFILE is system limit
				fmt.Println("[udp]read error:", err)
			} else if ne.Err.Error() == "use of closed network connection" {
				fmt.Println("[udp]Connection Closing:", remote.LocalAddr())
			} else {
				fmt.Println("[udp]error reading from:", remote.LocalAddr(), err)
			}
			return
		}
		// need improvement here
		ReqListLock.RLock()
		N, ok := ReqList[raddr.String()]
		ReqListLock.RUnlock()
		if ok {
			ss.WriteToUDP(append(N.Req, buf[:n]...), srcaddr)
		} else {
			header := ParseHeader(raddr)
			ss.WriteToUDP(append(header, buf[:n]...), srcaddr)
		}
		upTraffic(strconv.Itoa(ss.LocalAddr().(*net.UDPAddr).Port), n, srcaddr.IP.String())
	}
}
Beispiel #25
0
func (s *Server) UpdateRoomList(roomName string, room *ChatRoom, client *net.UDPAddr) {
	roomList := RoomListMessage{}
	roomList.Length = 0
	if len(room.clients) > 0 {
		roomList.Length = uint16(len(room.clients) - 1)
	}
	roomList.Room = roomName
	roomList.Addresses = make([]net.UDPAddr, roomList.Length)
	count := 0
	for _, other := range room.clients {
		if other.address.String() == client.String() {
			continue
		}
		roomList.Addresses[count] = *other.address
		count++
	}
	raw, err := roomList.RawMessage()
	if err != nil {
		panic(err)
	}
	message := &Message{raw, ROOM_LIST, false, uint16(len(raw.Data))}
	data, err := message.EncodeMessage()
	if err != nil {
		panic(err)
	}
	s.Conn.WriteTo(data, client)
	serverLogger.Println("Room list sent")
	if err != nil {
		panic(err)
	}
}
Beispiel #26
0
func (dhtNode *DhtNode) FindNode(node *KNode) {
	var id Id
	if node.Id != nil {
		id = node.Id.Neighbor()
	} else {
		id = dhtNode.node.Id.Neighbor()
	}
	tid := dhtNode.krpc.GenTID()
	v := make(map[string]interface{})
	v["t"] = fmt.Sprintf("%d", tid)
	v["y"] = "q"
	v["q"] = "find_node"
	args := make(map[string]string)
	args["id"] = string(id)
	args["target"] = string(GenerateID())
	v["a"] = args
	data, err := bencode.EncodeString(v)
	if err != nil {
		dhtNode.log.Fatalln(err)
	}

	raddr := new(net.UDPAddr)
	raddr.IP = node.Ip
	raddr.Port = node.Port

	err = dhtNode.network.Send([]byte(data), raddr)
	if err != nil {
		dhtNode.log.Println(err)
	}
}
Beispiel #27
0
// Called from RX when we are informed of new nodes.
func (dht *DHT) lReceivedNodes(nodes []NodeLocator, originAddr net.UDPAddr) error {
	for _, locator := range nodes {
		if locator.NodeID == dht.cfg.NodeID {
			// Skip references to ourself.
			continue
		}

		if locator.Addr.String() == originAddr.String() {
			// Ignore self-promotion.
			continue
		}

		n, wasInserted := dht.neighbourhood.routingTable.Node(locator.NodeID, locator.Addr)
		if !wasInserted {
			// Duplicate.
			continue
		}

		if dht.needMoreNodes() {
			select {
			case dht.recurseNodeChan <- locator.NodeID:
			default:
				// Too many find_node commands queued. The peer has already been added
				// to the routing table, so we're not losing any information.
			}
		}

		dht.lRequestMorePeers(n) // TODO: check this
	}

	return nil
}
Beispiel #28
0
// registerUser assumes that a user already was already chec
func registerUser(who *net.UDPAddr, loginMessage *message.Login) error {
	alias := loginMessage.Nickname
	// Check that he doesn't exist already
	var usr *User
	usr, isAlreadyRegistered := users[alias]
	if isAlreadyRegistered {
		if usr.Online {
			// That login is already used, choose a different one
			sendError(who, "Login already taken, choose a different one")
			return errors.New("Login already taken")
		}

		// Update to new status
		usr.Address = who
		usr.Online = true
		sendPendingMessages(usr)

	} else {
		// Create a new user
		usr = &User{alias,
			who,
			true,
			make([]string, BLOCKED_INITIAL),
			make([][]byte, 100),
		}
		users[usr.Alias] = usr
	}
	connections[who.String()] = usr
	m := message.NewLoginResponse(who.Port)
	mm, _ := xml.Marshal(m)
	sendMessageToUser(usr, mm)
	return nil
}
Beispiel #29
0
// Async
//
// Heartbeating serves two purposes: a) keeping NAT paths alive, and
// b) updating a remote peer's knowledge of our address, in the event
// it changes (e.g. because NAT paths expired).
func (conn *LocalConnection) ReceivedHeartbeat(remoteUDPAddr *net.UDPAddr, connUID uint64) {
	if remoteUDPAddr == nil || connUID != conn.uid {
		return
	}
	conn.sendAction(func() error {
		oldRemoteUDPAddr := conn.remoteUDPAddr
		old := conn.receivedHeartbeat
		conn.Lock()
		conn.remoteUDPAddr = remoteUDPAddr
		conn.receivedHeartbeat = true
		conn.Unlock()
		conn.heartbeatTimeout.Reset(HeartbeatTimeout)
		if !old {
			if err := conn.sendSimpleProtocolMsg(ProtocolConnectionEstablished); err != nil {
				return err
			}
		}
		if oldRemoteUDPAddr == nil {
			return conn.sendFastHeartbeats()
		} else if oldRemoteUDPAddr.String() != remoteUDPAddr.String() {
			log.Println("Peer", conn.remote.FullName(), "moved from", old, "to", remoteUDPAddr)
		}
		return nil
	})
}
Beispiel #30
0
func (server *Server) NewClient(remoteAddr *net.UDPAddr, nick string, reqId string) (*Client, int) {
	if remoteAddr == nil {
		panic("remoteAddr cannot be nil")
	}
	tmp := server.clients[remoteAddr.String()] // users[clientId]
	if tmp != nil {
		server.sendResponse("LOGIN", remoteAddr, strconv.Itoa(tmp.GetId())+";"+reqId)
		server.sendPastMessages(tmp)
		return nil, tmp.GetId()
	}

	maxId = int(atomic.AddInt32(&server.userId, 1))
	position := firstPosition[maxId%4]
	server.changesServer = true
	server.scoreNewClient(maxId)
	return &Client{
		maxId,
		nick,
		0,
		remoteAddr,
		remoteAddr.String(),
		server,
		float32(position[0]),
		float32(position[1]),
		fullLife,
		false,
		defaultDirection,
		0,
		false,
		false,
		0,
		0,
		0,
	}, 0
}