// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
// SPDX-License-Identifier: MIT

// Package stun contains ICE specific STUN code
package stun import ( ) var ( errGetXorMappedAddrResponse = errors.New("failed to get XOR-MAPPED-ADDRESS response") errMismatchUsername = errors.New("username mismatch") ) // GetXORMappedAddr initiates a STUN requests to serverAddr using conn, reads the response and returns // the XORMappedAddress returned by the STUN server. func ( net.PacketConn, net.Addr, time.Duration) (*stun.XORMappedAddress, error) { if > 0 { if := .SetReadDeadline(time.Now().Add()); != nil { return nil, } // Reset timeout after completion defer .SetReadDeadline(time.Time{}) //nolint:errcheck } , := stun.Build(stun.BindingRequest, stun.TransactionID) if != nil { return nil, } if _, = .WriteTo(.Raw, ); != nil { return nil, } const = 1280 := make([]byte, ) , , := .ReadFrom() if != nil { return nil, } := &stun.Message{Raw: [:]} if = .Decode(); != nil { return nil, } var stun.XORMappedAddress if = .GetFrom(); != nil { return nil, fmt.Errorf("%w: %v", errGetXorMappedAddrResponse, ) //nolint:errorlint } return &, nil } // AssertUsername checks that the given STUN message m has a USERNAME attribute with a given value. func ( *stun.Message, string) error { var stun.Username if := .GetFrom(); != nil { return } else if string() != { return fmt.Errorf("%w expected(%x) actual(%x)", errMismatchUsername, , string()) } return nil }