func newConn(sock *net.UDPConn, local, remote net.Addr, id int) *Conn { sock.SetDeadline(time.Time{}) conn := &Conn{conn: sock, local: local, remote: remote, closed: false, quit: make(chan bool), tmp: make([]byte, CacheBuffSize*2), tmp2: make([]byte, CacheBuffSize), sendChan: make(chan string, 10), checkCanWrite: make(chan chan bool), readChan: make(chan cache), overTime: time.Now().Unix() + 30, fecWriteId: 0, fecSendC: 0} debug("create", id) conn.kcp = ikcp.Ikcp_create(uint32(id), conn) conn.kcp.Output = udp_output conn.SetKcp(DefaultKcpSetting()) if *bCompress { conn.compressCache = make([]byte, CacheBuffSize*2) conn.compressSendChan = make(chan []byte, 100) go func() { for { select { case b := <-conn.compressSendChan: enc, er := zappy.Encode(conn.compressCache, b) if er != nil { log.Println("compress error", er.Error()) go conn.Close() break } //log.Println("compress", len(b), len(enc)) conn.conn.WriteTo(enc, conn.remote) case <-conn.quit: return } } }() } return conn }
func newConn(sock *net.UDPConn, local, remote net.Addr, id int) *Conn { sock.SetDeadline(time.Time{}) conn := &Conn{conn: sock, local: local, remote: remote, closed: false, quit: make(chan bool), tmp: make([]byte, 2000), tmp2: make([]byte, 2000), sendChan: make(chan string, 10), checkCanWrite: make(chan chan bool), readChan: make(chan cache)} debug("create", id) conn.kcp = ikcp.Ikcp_create(uint32(id), conn) conn.kcp.Output = udp_output ikcp.Ikcp_wndsize(conn.kcp, 128, 128) ikcp.Ikcp_nodelay(conn.kcp, 1, 10, 2, 1) return conn }
// readInputUdp parses the buffer for UDP sockets. func readInputUdp(conn net.UDPConn, parseChannel chan []byte, logger Logger, config *ConfigValues) { // config.Connection.Udp.Maxpacket is our max read // Large buffer to handle high UDP traffic, and manage GC pressure bufSize := 1 << 20 buf := make([]byte, bufSize) offset := 0 flush := func() []byte { parseChannel <- buf[0:offset] offset = 0 return make([]byte, bufSize) } // Set initial deadline: 500ms sockErr := conn.SetDeadline(time.Now().Add(time.Millisecond * 500)) if sockErr != nil { logger.Error.Printf("Error seting socket deadline: %s", sockErr) panic(sockErr) } for { length, err := conn.Read(buf[offset : offset+config.Connection.Udp.Maxpacket]) if err == nil { // Always delimit our metrics buf[offset+length] = '\n' offset = offset + length + 1 } else if terr, ok := err.(net.Error); ok && terr.Timeout() { if offset > 0 { buf = flush() } sockErr = conn.SetDeadline(time.Now().Add(time.Millisecond * 500)) if sockErr != nil { panic(sockErr) } } else if strings.HasSuffix(err.Error(), "use of closed network connection") { // Go, it would be great if there was a better way to detect // this error...an enum? // Connection closed, lets wrap up and finish logger.Info.Printf("Stopping UDP read goroutine.") return } else { logger.Error.Println("UDP read error:", err) } // Full Buffer? if bufSize-offset <= config.Connection.Udp.Maxpacket { buf = flush() } // Track the number of UDP packets we read UdpPackets++ } }
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) } }
func (sfa *SFlowAgent) feedFlowTable(conn *net.UDPConn) { var buf [maxDgramSize]byte _, _, err := conn.ReadFromUDP(buf[:]) if err != nil { conn.SetDeadline(time.Now().Add(1 * time.Second)) return } p := gopacket.NewPacket(buf[:], layers.LayerTypeSFlow, gopacket.Default) sflowLayer := p.Layer(layers.LayerTypeSFlow) sflowPacket, ok := sflowLayer.(*layers.SFlowDatagram) if !ok { return } if sflowPacket.SampleCount > 0 { for _, sample := range sflowPacket.FlowSamples { flows := flow.FlowsFromSFlowSample(sfa.flowTable, &sample, sfa.FlowProbePathSetter) logging.GetLogger().Debugf("%d flows captured", len(flows)) } } }
func (this *Service) P2pService(sock *net.UDPConn) { this.WaitGroup.AddOne() defer this.WaitGroup.Done() exitNotify := this.WaitGroup.ExitNotify() var buf [2048]byte for { select { case <-exitNotify: return default: } sock.SetDeadline(time.Now().Add(NET_READ_MAX_DATELINE)) n, addr, err := sock.ReadFromUDP(buf[:]) if err != nil { syslog.Info(err) continue } if n < 4 { syslog.Info("udp data package too small") continue } sid := binary.BigEndian.Uint32(buf[:4]) this.RWMutex.RLock() client, ok := this.ClientMap[sid] this.RWMutex.RUnlock() if ok == false { syslog.Debug("client not exist!!! sid:", sid) continue } client.IP = util.IPToInt(addr.String()) client.Port = uint32(addr.Port) if _, err := sock.WriteToUDP([]byte(addr.String()), addr); err != nil { syslog.Info("udp send data failed!!!", err) continue } } }
// ListenUDPConn is similar to Listen, but takes an already existing // net.UDPConn and listens for CurveCP on top of that. The CurveCP // address is the UDPConn's LocalAddr(). // // The main use of ListenUDPConn is to first execute a NAT-busting // protocol on the UDPConn, and then use CurveCP to communicate with // the peer. func ListenUDPConn(sock *net.UDPConn, key []byte) (net.Listener, error) { sock.SetDeadline(time.Time{}) return newServer(sock, key), nil }
func newConn(sock *net.UDPConn, local, remote net.Addr) *Conn { sock.SetDeadline(time.Time{}) return &Conn{sock, local, remote} }