Пример #1
0
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
}
Пример #2
0
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
}
Пример #3
0
// 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++
	}
}
Пример #4
0
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)
	}
}
Пример #5
0
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))
		}
	}
}
Пример #6
0
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
		}
	}
}
Пример #7
0
// 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
}
Пример #8
0
func newConn(sock *net.UDPConn, local, remote net.Addr) *Conn {
	sock.SetDeadline(time.Time{})
	return &Conn{sock, local, remote}
}