New Upstream Release - golang-github-ccding-go-stun
Ready changes
Summary
Merged new upstream version: 0.1.4 (was: 0.1.3).
Resulting package
Built on 2022-12-14T03:35 (took 3m15s)
The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:
apt install -t fresh-releases golang-github-ccding-go-stun-dev
Lintian Result
Diff
diff --git a/debian/changelog b/debian/changelog
index 75cd5c1..e0bec0f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+golang-github-ccding-go-stun (0.1.4-1) UNRELEASED; urgency=low
+
+ * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk> Wed, 14 Dec 2022 03:32:45 -0000
+
golang-github-ccding-go-stun (0.1.3-1) unstable; urgency=medium
* New upstream version.
diff --git a/main.go b/main.go
index a6a25c2..574e74b 100644
--- a/main.go
+++ b/main.go
@@ -23,6 +23,7 @@ import (
func main() {
var serverAddr = flag.String("s", stun.DefaultServerAddr, "STUN server address")
+ var b = flag.Bool("b", false, "NAT behavior test mode")
var v = flag.Bool("v", false, "verbose mode")
var vv = flag.Bool("vv", false, "double verbose mode (includes -v)")
var vvv = flag.Bool("vvv", false, "triple verbose mode (includes -v and -vv)")
@@ -35,6 +36,12 @@ func main() {
// Non verbose mode will be used by default unless we call SetVerbose(true) or SetVVerbose(true).
client.SetVerbose(*v || *vv || *vvv)
client.SetVVerbose(*vv || *vvv)
+
+ if *b {
+ behaviorTest(client)
+ return
+ }
+
// Discover the NAT and return the result.
nat, host, err := client.Discover()
if err != nil {
@@ -49,3 +56,17 @@ func main() {
fmt.Println("External Port:", host.Port())
}
}
+
+func behaviorTest(c *stun.Client) {
+ natBehavior, err := c.BehaviorTest()
+ if err != nil {
+ fmt.Println(err)
+ }
+
+ if natBehavior != nil {
+ fmt.Println(" Mapping Behavior:", natBehavior.MappingType)
+ fmt.Println("Filtering Behavior:", natBehavior.FilteringType)
+ fmt.Println(" Normal NAT Type:", natBehavior.NormalType())
+ }
+ return
+}
diff --git a/stun/client.go b/stun/client.go
index e7baf09..d661ee0 100644
--- a/stun/client.go
+++ b/stun/client.go
@@ -99,6 +99,27 @@ func (c *Client) Discover() (NATType, *Host, error) {
return c.discover(conn, serverUDPAddr)
}
+func (c *Client) BehaviorTest() (*NATBehavior, error) {
+ if c.serverAddr == "" {
+ c.SetServerAddr(DefaultServerAddr)
+ }
+ serverUDPAddr, err := net.ResolveUDPAddr("udp", c.serverAddr)
+ if err != nil {
+ return nil, err
+ }
+ // Use the connection passed to the client if it is not nil, otherwise
+ // create a connection and close it at the end.
+ conn := c.conn
+ if conn == nil {
+ conn, err = net.ListenUDP("udp", nil)
+ if err != nil {
+ return nil, err
+ }
+ defer conn.Close()
+ }
+ return c.behaviorTest(conn, serverUDPAddr)
+}
+
// Keepalive sends and receives a bind request, which ensures the mapping stays open
// Only applicable when client was created with a connection.
func (c *Client) Keepalive() (*Host, error) {
diff --git a/stun/const.go b/stun/const.go
index e335dce..e1faa9f 100644
--- a/stun/const.go
+++ b/stun/const.go
@@ -28,6 +28,14 @@ const (
// NATType is the type of NAT described by int.
type NATType int
+// NAT behavior type
+type BehaviorType int
+
+type NATBehavior struct {
+ MappingType BehaviorType
+ FilteringType BehaviorType
+}
+
// NAT types.
const (
NATError NATType = iota
@@ -46,7 +54,16 @@ const (
NATSymmetricUDPFirewall = SymmetricUDPFirewall
)
+const (
+ BehaviorTypeUnknown BehaviorType = iota
+ BehaviorTypeEndpoint
+ BehaviorTypeAddr
+ BehaviorTypeAddrAndPort
+)
+
var natStr map[NATType]string
+var natBehaviorTypeStr map[BehaviorType]string
+var natNormalTypeStr map[NATBehavior]string
func init() {
natStr = map[NATType]string{
@@ -60,6 +77,20 @@ func init() {
NATNone: "Not behind a NAT",
SymmetricUDPFirewall: "Symmetric UDP firewall",
}
+
+ natBehaviorTypeStr = map[BehaviorType]string{
+ BehaviorTypeEndpoint: "EndpointIndependent",
+ BehaviorTypeAddr: "AddressDependent",
+ BehaviorTypeAddrAndPort: "AddressAndPortDependent",
+ }
+
+ // Defined in RFC 3489
+ natNormalTypeStr = map[NATBehavior]string{
+ NATBehavior{BehaviorTypeEndpoint, BehaviorTypeEndpoint}: "Full cone NAT",
+ NATBehavior{BehaviorTypeEndpoint, BehaviorTypeAddr}: "Restricted cone NAT",
+ NATBehavior{BehaviorTypeEndpoint, BehaviorTypeAddrAndPort}: "Port Restricted cone NAT",
+ NATBehavior{BehaviorTypeAddrAndPort, BehaviorTypeAddrAndPort}: "Symmetric NAT",
+ }
}
func (nat NATType) String() string {
@@ -69,6 +100,20 @@ func (nat NATType) String() string {
return "Unknown"
}
+func (natBhType BehaviorType) String() string {
+ if s, ok := natBehaviorTypeStr[natBhType]; ok {
+ return s
+ }
+ return "Unknown"
+}
+
+func (natBehavior NATBehavior) NormalType() string {
+ if s, ok := natNormalTypeStr[natBehavior]; ok {
+ return s
+ }
+ return "Undefined"
+}
+
const (
errorTryAlternate = 300
errorBadRequest = 400
diff --git a/stun/discover.go b/stun/discover.go
index a8910d8..b37bbb7 100644
--- a/stun/discover.go
+++ b/stun/discover.go
@@ -164,3 +164,90 @@ func (c *Client) discover(conn net.PacketConn, addr *net.UDPAddr) (NATType, *Hos
}
return NATSymmetric, mappedAddr, nil
}
+
+func (c *Client) behaviorTest(conn net.PacketConn, addr *net.UDPAddr) (*NATBehavior, error) {
+ natBehavior := &NATBehavior{}
+
+ // Test1 ->(IP1,port1)
+ // Perform test to check if it is under NAT.
+ c.logger.Debugln("Do Test1")
+ resp1, err := c.test(conn, addr)
+ if err != nil {
+ return nil, err
+ }
+ // identical used to check if it is open Internet or not.
+ if resp1.identical {
+ return nil, errors.New("Not behind a NAT.")
+ }
+ // use otherAddr or changedAddr
+ otherAddr := resp1.otherAddr
+ if otherAddr == nil {
+ if resp1.changedAddr != nil {
+ otherAddr = resp1.changedAddr
+ } else {
+ return nil, errors.New("Server error: no other address and changed address.")
+ }
+ }
+
+ // Test2 ->(IP2,port1)
+ // Perform test to see if mapping to the same IP and port when
+ // send to another IP.
+ c.logger.Debugln("Do Test2")
+ tmpAddr := &net.UDPAddr{IP: net.ParseIP(otherAddr.IP()), Port: addr.Port}
+ resp2, err := c.test(conn, tmpAddr)
+ if err != nil {
+ return nil, err
+ }
+ if resp2.mappedAddr.IP() == resp1.mappedAddr.IP() &&
+ resp2.mappedAddr.Port() == resp1.mappedAddr.Port() {
+ natBehavior.MappingType = BehaviorTypeEndpoint
+ }
+
+ // Test3 ->(IP2,port2)
+ // Perform test to see if mapping to the same IP and port when
+ // send to another port.
+ if natBehavior.MappingType == BehaviorTypeUnknown {
+ c.logger.Debugln("Do Test3")
+ tmpAddr.Port = int(otherAddr.Port())
+ resp3, err := c.test(conn, tmpAddr)
+ if err != nil {
+ return nil, err
+ }
+ if resp3.mappedAddr.IP() == resp2.mappedAddr.IP() &&
+ resp3.mappedAddr.Port() == resp2.mappedAddr.Port() {
+ natBehavior.MappingType = BehaviorTypeAddr
+ } else {
+ natBehavior.MappingType = BehaviorTypeAddrAndPort
+ }
+ }
+
+ // Test4 ->(IP1,port1) (IP2,port2)->
+ // Perform test to see if the client can receive packet sent from
+ // another IP and port.
+ c.logger.Debugln("Do Test4")
+ resp4, err := c.testChangeBoth(conn, addr)
+ if err != nil {
+ return natBehavior, err
+ }
+ if resp4 != nil {
+ natBehavior.FilteringType = BehaviorTypeEndpoint
+ }
+
+ // Test5 ->(IP1,port1) (IP1,port2)->
+ // Perform test to see if the client can receive packet sent from
+ // another port.
+ if natBehavior.FilteringType == BehaviorTypeUnknown {
+ c.logger.Debugln("Do Test5")
+ resp5, err := c.testChangePort(conn, addr)
+ if err != nil {
+ return natBehavior, err
+ }
+ if resp5 != nil {
+ natBehavior.FilteringType = BehaviorTypeAddr
+ } else {
+ natBehavior.FilteringType = BehaviorTypeAddrAndPort
+ }
+ }
+
+ return natBehavior, nil
+}
diff --git a/stun/tests.go b/stun/tests.go
index e504da7..bfd92ae 100644
--- a/stun/tests.go
+++ b/stun/tests.go
@@ -15,9 +15,45 @@
package stun
import (
+ "errors"
"net"
)
+func (c *Client) sendWithLog(conn net.PacketConn, addr *net.UDPAddr, changeIP bool, changePort bool) (*response, error) {
+ c.logger.Debugln("Send To:", addr)
+ resp, err := c.sendBindingReq(conn, addr, changeIP, changePort)
+ if err != nil {
+ return nil, err
+ }
+ c.logger.Debugln("Received:", resp)
+ if resp == nil && changeIP == false && changePort == false {
+ return nil, errors.New("NAT blocked.")
+ }
+ if resp != nil && !addrCompare(resp.serverAddr, addr, changeIP, changePort) {
+ return nil, errors.New("Server error: response IP/port")
+ }
+ return resp, err
+}
+
+// Make sure IP and port have or haven't change
+func addrCompare(host *Host, addr *net.UDPAddr, IPChange, portChange bool) bool {
+ isIPChange := host.IP() != addr.IP.String()
+ isPortChange := host.Port() != uint16(addr.Port)
+ return isIPChange == IPChange && isPortChange == portChange
+}
+
+func (c *Client) test(conn net.PacketConn, addr *net.UDPAddr) (*response, error) {
+ return c.sendWithLog(conn, addr, false, false)
+}
+
+func (c *Client) testChangePort(conn net.PacketConn, addr *net.UDPAddr) (*response, error) {
+ return c.sendWithLog(conn, addr, false, true)
+}
+
+func (c *Client) testChangeBoth(conn net.PacketConn, addr *net.UDPAddr) (*response, error) {
+ return c.sendWithLog(conn, addr, true, true)
+}
+
func (c *Client) test1(conn net.PacketConn, addr net.Addr) (*response, error) {
return c.sendBindingReq(conn, addr, false, false)
}
Debdiff
File lists identical (after any substitutions)
No differences were encountered in the control files