Example #1
0
func test1(conn net.PacketConn, addr net.Addr, softwareName string) (*packet, net.Addr, bool, *Host, error) {
	packet, err := sendBindingReq(conn, addr, softwareName)
	if err != nil {
		return nil, nil, false, nil, err
	}
	if packet == nil {
		return nil, nil, false, nil, nil
	}

	// RFC 3489 doesn't require the server return XOR mapped address.
	hostMappedAddr := packet.xorMappedAddr()
	if hostMappedAddr == nil {
		hostMappedAddr = packet.mappedAddr()
		if hostMappedAddr == nil {
			return nil, nil, false, nil, errors.New("No mapped address.")
		}
	}

	identical := isLocalAddress(conn.LocalAddr().String(), hostMappedAddr.TransportAddr())

	hostChangedAddr := packet.changedAddr()
	if hostChangedAddr == nil {
		return packet, nil, identical, hostMappedAddr, nil
	}
	changedAddrStr := hostChangedAddr.TransportAddr()
	changedAddr, err := net.ResolveUDPAddr("udp", changedAddrStr)
	if err != nil {
		return nil, nil, false, nil, errors.New("Failed to resolve changed address.")
	}
	return packet, changedAddr, identical, hostMappedAddr, nil
}
Example #2
0
func newConnection(c net.PacketConn, addr net.Addr, tq *timerQueue, tag []byte, closed func()) *connection {
	conn := &connection{
		Cond:      sync.Cond{L: new(sync.Mutex)},
		addr:      addr,
		localAddr: c.LocalAddr(),
		closeWait: make(chan struct{}),
	}

	var tag3 [3]byte
	copy(tag3[:], tag)
	go conn.proc(c, tq, tag3, closed)
	return conn
}
Example #3
0
// Serve accepts incoming TFTP read requests on the listener l,
// creating a new service goroutine for each. The service goroutines
// use handler to get a byte stream and send it to the client.
func Serve(l net.PacketConn, handler Handler) {
	Log("Listening on %s", l.LocalAddr())
	buf := make([]byte, 512)
	for {
		n, addr, err := l.ReadFrom(buf)
		if err != nil {
			Log("Reading from socket: %s", err)
			continue
		}

		req, err := parseRRQ(addr, buf[:n])
		if err != nil {
			Debug("parseRRQ: %s", err)
			l.WriteTo(mkError(err), addr)
			continue
		}

		go transfer(addr, req, handler)
	}
}
Example #4
0
func (self *UdpServer) start() error {
	var conn net.PacketConn
	var e error

	if nil == self.listenAddr {
		conn, e = net.ListenPacket("udp", self.origin)
	} else {
		conn, e = net.ListenPacket("udp", self.listenAddr.String())
	}
	if nil != e {
		return e
	}

	self.conn = conn
	self.listenAddr = conn.LocalAddr()

	self.waitGroup.Add(1)
	go self.serve()

	return nil
}
Example #5
0
func (svr *snmpTestServer) Start() {
	var in net.PacketConn
	var e error

	if nil == svr.listenAddr {
		in, e = net.ListenPacket("udp", svr.origin)
		svr.t.Log("[test_server]", "listen at", in.LocalAddr())
	} else {
		in, e = net.ListenPacket("udp", svr.listenAddr.String())
		svr.t.Log("[test_server]", "listen at", svr.listenAddr.String())
	}
	if nil != e {
		panic(e.Error())
	}

	svr.isFirstListen = false
	svr.waitGroup.Add(1)
	svr.conn = in
	svr.listenAddr = in.LocalAddr()

	go serveTestUdp2(svr)

}
Example #6
0
// Listen announces on existing packet-based connection
func ListenConn(conn net.PacketConn) (net.Listener, error) {
	l := &listener{
		Cond: sync.Cond{
			L: new(sync.Mutex),
		},
		addr: conn.LocalAddr(),
	}

	rld := &receiveLoopData{
		Cond: sync.Cond{
			L: new(sync.Mutex),
		},
		buffers: [][]byte{
			make([]byte, 65536),
			make([]byte, 65536),
			make([]byte, 65536),
		},
	}

	pld := &processLoopData{
		Cond: sync.Cond{
			L: new(sync.Mutex),
		},
	}

	l.stopListening = func() {
		pld.L.Lock()
		pld.rejectNewConnections = true
		pld.L.Unlock()
		pld.Signal()
	}

	go receiveLoop(conn, l, rld, pld)
	go processLoop(conn, l, rld, pld)
	return l, nil
}
	logMessages []*events.LogMessage
	udpConn     net.PacketConn
)

var _ = Describe("LogIntegration", func() {
	Context("with standard initialization", func() {
		origin := []string{"test-origin"}

		BeforeEach(func() {
			var err error
			logMessages = nil
			udpConn, err = net.ListenPacket("udp4", ":0")
			Expect(err).ToNot(HaveOccurred())

			go listenForLogs()
			udpAddr := udpConn.LocalAddr().(*net.UDPAddr)
			dropsonde.Initialize(fmt.Sprintf("localhost:%d", udpAddr.Port), origin...)
			sender := metric_sender.NewMetricSender(dropsonde.AutowiredEmitter())
			batcher := metricbatcher.New(sender, 100*time.Millisecond)
			metrics.Initialize(sender, batcher)
		})

		AfterEach(func() {
			udpConn.Close()
		})

		It("sends dropped error message for messages which are just under 64k and don't fit in UDP packet", func() {
			logSender := log_sender.NewLogSender(dropsonde.AutowiredEmitter(), time.Second, loggertesthelper.Logger())

			const length = 64*1024 - 1
			reader := strings.NewReader(strings.Repeat("s", length) + "\n")
		})
	})

	Describe("Emit()", func() {
		var udpEmitter emitter.ByteEmitter

		Context("when the agent is listening", func() {

			var agentListener net.PacketConn

			BeforeEach(func() {
				var err error
				agentListener, err = net.ListenPacket("udp4", "")
				Expect(err).ToNot(HaveOccurred())

				udpEmitter, err = emitter.NewUdpEmitter(agentListener.LocalAddr().String())
				Expect(err).ToNot(HaveOccurred())
			})

			AfterEach(func() {
				agentListener.Close()
			})

			It("should send the data", func(done Done) {
				err := udpEmitter.Emit(testData)
				Expect(err).ToNot(HaveOccurred())

				buffer := make([]byte, 4096)
				readCount, _, err := agentListener.ReadFrom(buffer)
				Expect(err).ToNot(HaveOccurred())
				Expect(buffer[:readCount]).To(Equal(testData))
Example #9
0
		for {
			buffer := make([]byte, 1024)
			n, _, err := testMetricsListener.ReadFrom(buffer)
			if err != nil {
				close(testMetricsChan)
				return
			}

			var envelope events.Envelope
			err = proto.Unmarshal(buffer[:n], &envelope)
			Expect(err).NotTo(HaveOccurred())
			testMetricsChan <- &envelope
		}
	}()

	port, err := strconv.Atoi(strings.TrimPrefix(testMetricsListener.LocalAddr().String(), "127.0.0.1:"))
	Expect(err).NotTo(HaveOccurred())

	client = bbs.NewClient(bbsURL.String())

	bbsArgs = testrunner.Args{
		Address:                  bbsAddress,
		AdvertiseURL:             bbsURL.String(),
		AuctioneerAddress:        auctioneerServer.URL(),
		ConsulCluster:            consulRunner.ConsulCluster(),
		DropsondePort:            port,
		EtcdCluster:              etcdUrl, // etcd is still being used to test version migration in migration_version_test.go
		DatabaseDriver:           sqlRunner.DriverName(),
		DatabaseConnectionString: sqlRunner.ConnectionString(),
		MetricsReportInterval:    10 * time.Millisecond,
		HealthAddress:            bbsHealthAddress,
Example #10
0
// receives packets from the receive loop and dispatches them
// to their corresponding connections
func processLoop(c net.PacketConn, l *listener, rld *receiveLoopData, pld *processLoopData) {

	var (
		quit        bool
		wg          = new(sync.WaitGroup)
		tq          = newTimerQueue()
		connections = struct {
			sync.RWMutex
			M map[uint32]*connection
		}{
			M: make(map[uint32]*connection),
		}
	)

	// keep a refcount to `c` for ourselves
	wg.Add(1)
	defer wg.Done()

	// wait for all pending connections, then close the socket
	go func() {
		wg.Wait()
		c.Close()
		tq.Close()
	}()

	// generate a new key for cookies
	cookieKey := make([]byte, sha1.Size)
	if _, err := crand.Read(cookieKey); err != nil {
		l.L.Lock()
		l.err = fmt.Errorf("Failed to generate cookie secret: %v", err)
		l.L.Unlock()
		l.Broadcast()
		return
	}

	sig := hmac.New(sha1.New, cookieKey)

	// generate addler32(localaddr)
	var localAddrSum [4]byte
	binary.LittleEndian.PutUint32(localAddrSum[:], adler32.Checksum([]byte(c.LocalAddr().String())))

	shouldWait := func() bool {
		waitOnConnections := pld.rejectNewConnections && pld.remainingConnections == 0
		return pld.err == nil && len(pld.Q) == 0 && !waitOnConnections
	}

	var packets []processLoopPacket

	for !quit {
		// wait for a packet to become available
		pld.L.Lock()
		for shouldWait() {
			pld.Wait()
		}
		rejectNewConnections := pld.rejectNewConnections
		pldErr := pld.err
		quit = pldErr != nil
		packets, pld.Q = pld.Q, packets[:0]
		remainingConnections := pld.remainingConnections
		pld.L.Unlock()

		if rejectNewConnections && remainingConnections == 0 {
			quit = true
		}

		// process packets
		for ii := range packets {
			buffer, addr := packets[ii].D, packets[ii].A

			switch PacketType(buffer[0]) {
			case PacketInit:
				// are we accepting new connections?
				if rejectNewConnections {
					continue
				}

				// verify length
				const MinInitPacketLength = 9
				if len(buffer) < MinInitPacketLength {
					continue
				}

				// verify protocol magic
				if !bytes.Equal(buffer[1:5], protocolMagic) {
					continue
				}

				// verify version
				if buffer[5] != version1 {
					sendAbort(c, addr, buffer[6:9])
					continue
				}

				var outgoing [32]byte
				now := time.Now()
				outgoing[0] = byte(PacketCookie)
				if _, err := crand.Read(outgoing[1:4]); err != nil {
					return
				}
				copy(outgoing[4:7], buffer[6:9])
				outgoing[7] = version1
				binary.LittleEndian.PutUint32(outgoing[8:12], uint32(now.Add(5*time.Second).Unix()+1))

				sig.Reset()
				sig.Write(outgoing[1:12])
				sig.Write(localAddrSum[:])
				sig.Sum(outgoing[1:12])
				c.WriteTo(outgoing[:], addr)

			case PacketCookieEcho:

				// are we accepting new connections
				if rejectNewConnections {
					continue
				}

				// verify length
				const CookieEchoPacketLength = 32
				if len(buffer) != CookieEchoPacketLength {
					continue
				}

				// verify signature
				sig.Reset()
				sig.Write(buffer[1:12])
				sig.Write(localAddrSum[:])
				if !hmac.Equal(sig.Sum(nil), buffer[12:]) {
					continue
				}

				// verify version
				if buffer[7] != version1 {
					sendAbort(c, addr, buffer[1:4])
					continue
				}

				// vetify timeout
				now := time.Now()
				if time.Unix(int64(binary.LittleEndian.Uint32(buffer[8:12])), 0).Before(now) {
					sendAbort(c, addr, buffer[1:4])
					continue
				}

				// decode connection tag to uin32
				tagId := binary.LittleEndian.Uint32(buffer[3:7]) >> 8

				connections.RLock()
				_, ok := connections.M[tagId]
				connections.RUnlock()
				// create new connection
				if !ok {

					// create connection
					wg.Add(1)
					connections.Lock()
					conn := newConnection(c, addr, tq, buffer[1:4], func() {
						connections.Lock()
						delete(connections.M, tagId)
						connections.Unlock()

						wg.Done()

						pld.L.Lock()
						pld.remainingConnections--
						remain := pld.remainingConnections
						pld.L.Unlock()

						if remain == 0 {
							pld.Signal()
						}
					})

					connections.M[tagId] = conn
					connections.Unlock()

					pld.L.Lock()
					pld.remainingConnections++
					pld.L.Unlock()

					l.L.Lock()
					l.pending = append(l.pending, conn)
					l.L.Unlock()
					l.Signal()
				}

				// send COOKIE-ACK
				var outgoing [4]byte
				outgoing[0] = byte(PacketCookieAck)
				copy(outgoing[1:4], buffer[1:4])
				c.WriteTo(outgoing[:], addr)

			default:
				// parse connection tag
				tagId := binary.LittleEndian.Uint32(buffer[0:4]) >> 8
				connections.RLock()
				conn, ok := connections.M[tagId]
				connections.RUnlock()

				// discard packets addressed to unknown connections
				if !ok {
					sendAbort(c, addr, buffer[1:4])
					continue
				}

				// copy the packet data so we can reuse the buffer
				p := NewPacket(len(buffer))
				copy(p.D, buffer)

				// queue the packet onto the connection
				conn.L.Lock()
				conn.Incoming = append(conn.Incoming, p)
				conn.L.Unlock()
				conn.Signal()
			}
		}

		// return the packet to the receive loop
		rld.L.Lock()
		for ii := range packets {
			rld.buffers = append(rld.buffers, packets[ii].D)
		}
		rld.L.Unlock()
		rld.Signal()

		// if we were signaled to quit, terminate existing connections
		if pldErr != nil {
			connections.Lock()
			m := connections.M
			connections.M = make(map[uint32]*connection)
			connections.Unlock()

			for _, c := range m {
				c.closeWithError(pldErr)
			}
		}
	}
}