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{}{} }
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()) } } }
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 }
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()) } }
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 }
/* 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 }
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 }
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) } } }
// 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 }
//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 }
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 }
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 }
// 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!") } }
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) }
// 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 }
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 }
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 }
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()) } }
// 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) } }
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 } }() }
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 }
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) }
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()) } }
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) } }
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) } }
// 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 }
// 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 }
// 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 }) }
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 }