예제 #1
0
파일: client.go 프로젝트: ricochet2200/gun
// Sends a request where you expect to get a response back
func (this *Client) SendReqRes(req *msg.Message) (*Connection, error) {

	conn, err := net.DialTimeout("tcp", this.server, 15*time.Second)
	if err != nil {
		log.Println("Failed to create connection: ", err)
		return nil, err
	}

	laddr := conn.LocalAddr()
	ip := laddr.(*net.TCPAddr).IP
	port := laddr.(*net.TCPAddr).Port

	xor := msg.NewXORAddress(ip, port, req.Header())
	req.AddAttribute(xor)

	if this.nonce != nil && this.realm != nil {
		req.AddAttribute(this.user)
		req.AddAttribute(this.realm)
		req.AddAttribute(this.nonce)

		username := this.user.String()
		realm := this.realm.String()

		integrity := msg.NewIntegrityAttr(username, this.password, realm, req)
		req.AddAttribute(integrity)
	}

	conn.Write(req.EncodeMessage())

	res, err := msg.DecodeMessage(conn)

	if err != nil {
		conn.Close()
		return nil, err
	}

	if eattr, err := res.Attribute(msg.ErrorCode); err == nil {
		if code, err := eattr.(*msg.StunError).Code(); err == nil {
			log.Println("error code", code)
			switch code {

			case msg.StaleNonce:
				log.Println("Stale Nonce, calling authenticate...")
				return this.Authenticate(res, req)

			case msg.Unauthorized:
				log.Println("unauthorized")

				if _, err := req.Attribute(msg.MessageIntegrity); err == nil {
					conn.Close()
					return nil, errors.New("Invalid credentials")
				} else {
					return this.Authenticate(res, req)
				}
			}
		}
	}

	return &Connection{res, conn}, nil
}
예제 #2
0
func (this *Connection) Write(res *msg.Message) {

	xorAddr := msg.NewXORAddress(this.IP(), this.Port(), res.Header())
	res.AddAttribute(xorAddr)

	if this.HasAuth {
		i := msg.NewIntegrityAttr(this.User, this.Passwd, this.Realm, this.Req)
		res.AddAttribute(i)
	}

	this.Out.Write(res.EncodeMessage())
}