Beispiel #1
0
func getReflexive(sock *net.UDPConn) (*net.UDPAddr, error) {
	serverAddr, err := net.ResolveUDPAddr("udp", *stunserver)
	if err != nil {

		return nil, errors.New("Couldn't resolve STUN server")
	}

	var tid [12]byte
	if _, err = rand.Read(tid[:]); err != nil {
		return nil, err
	}

	request, err := stun.BindRequest(tid[:], nil, true, false)
	if err != nil {
		return nil, err
	}

	n, err := sock.WriteTo(request, serverAddr)
	if err != nil {
		return nil, err
	}
	if n < len(request) {
		return nil, err
	}

	var buf [1024]byte
	n, _, err = sock.ReadFromUDP(buf[:])
	if err != nil {
		return nil, err
	}

	packet, err := stun.ParsePacket(buf[:n], nil)
	if err != nil {
		return nil, err
	}

	if packet.Class != stun.ClassSuccess || packet.Method != stun.MethodBinding || packet.Addr == nil || !bytes.Equal(tid[:], packet.Tid[:]) {
		return nil, errors.New("No address provided by STUN server")
	}

	return packet.Addr, nil
}
Beispiel #2
0
func (e *attemptEngine) xmit() (time.Time, error) {
	now := time.Now()
	var ret time.Time
	var err error

	for i := range e.attempts {
		if e.attempts[i].timeout.Before(now) {
			e.attempts[i].timeout = time.Now().Add(probeTimeout)
			e.attempts[i].tid, err = stun.RandomTid()
			if err != nil {
				return time.Time{}, err
			}
			packet, err := stun.BindRequest(e.attempts[i].tid, nil, false, e.attempts[i].chosen)
			if err != nil {
				return time.Time{}, err
			}
			e.sock.WriteToUDP(packet, e.attempts[i].Addr)
		}
		if ret.IsZero() || e.attempts[i].timeout.Before(ret) {
			ret = e.attempts[i].timeout
		}
	}
	return ret, nil
}