-
Notifications
You must be signed in to change notification settings - Fork 320
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Also update .goreleaser binary names to be more self documenting Resolves #87
- Loading branch information
Showing
5 changed files
with
238 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
*.sw[poe] | ||
examples/turn-client/turn-client | ||
examples/turn-server/simple/add-software-attribute | ||
examples/turn-server/simple/log | ||
examples/turn-client/tcp/tcp | ||
examples/turn-client/udp/udp | ||
examples/turn-server/add-software-attribute/add-software-attribute | ||
examples/turn-server/log/log | ||
examples/turn-server/simple/simple | ||
examples/turn-server/simple/tcp | ||
examples/turn-server/tcp/tcp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
package main | ||
|
||
import ( | ||
"flag" | ||
"fmt" | ||
"log" | ||
"net" | ||
"strings" | ||
"time" | ||
|
||
"github.com/pion/logging" | ||
"github.com/pion/turn/v2" | ||
) | ||
|
||
func main() { | ||
host := flag.String("host", "", "TURN Server name.") | ||
port := flag.Int("port", 3478, "Listening port.") | ||
user := flag.String("user", "", "A pair of username and password (e.g. \"user=pass\")") | ||
realm := flag.String("realm", "pion.ly", "Realm (defaults to \"pion.ly\")") | ||
ping := flag.Bool("ping", false, "Run ping test") | ||
flag.Parse() | ||
|
||
if len(*host) == 0 { | ||
log.Fatalf("'host' is required") | ||
} | ||
|
||
if len(*user) == 0 { | ||
log.Fatalf("'user' is required") | ||
} | ||
|
||
// Dial TURN Server | ||
turnServerAddr := fmt.Sprintf("%s:%d", *host, *port) | ||
conn, err := net.Dial("tcp", turnServerAddr) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
cred := strings.Split(*user, "=") | ||
|
||
// Start a new TURN Client and wrap our net.Conn in a STUNConn | ||
// This allows us to simulate datagram based communication over a net.Conn | ||
cfg := &turn.ClientConfig{ | ||
STUNServerAddr: turnServerAddr, | ||
TURNServerAddr: turnServerAddr, | ||
Conn: turn.NewSTUNConn(conn), | ||
Username: cred[0], | ||
Password: cred[1], | ||
Realm: *realm, | ||
LoggerFactory: logging.NewDefaultLoggerFactory(), | ||
} | ||
|
||
client, err := turn.NewClient(cfg) | ||
if err != nil { | ||
panic(err) | ||
} | ||
defer client.Close() | ||
|
||
// Start listening on the conn provided. | ||
err = client.Listen() | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
// Allocate a relay socket on the TURN server. On success, it | ||
// will return a net.PacketConn which represents the remote | ||
// socket. | ||
relayConn, err := client.Allocate() | ||
if err != nil { | ||
panic(err) | ||
} | ||
defer func() { | ||
if closeErr := relayConn.Close(); closeErr != nil { | ||
panic(closeErr) | ||
} | ||
}() | ||
|
||
// The relayConn's local address is actually the transport | ||
// address assigned on the TURN server. | ||
log.Printf("relayed-address=%s", relayConn.LocalAddr().String()) | ||
|
||
// If you provided `-ping`, perform a ping test agaist the | ||
// relayConn we have just allocated. | ||
if *ping { | ||
err = doPingTest(client, relayConn) | ||
if err != nil { | ||
panic(err) | ||
} | ||
} | ||
} | ||
|
||
func doPingTest(client *turn.Client, relayConn net.PacketConn) error { | ||
// Send BindingRequest to learn our external IP | ||
mappedAddr, err := client.SendBindingRequest() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Set up pinger socket (pingerConn) | ||
pingerConn, err := net.ListenPacket("udp4", "0.0.0.0:0") | ||
if err != nil { | ||
panic(err) | ||
} | ||
defer func() { | ||
if closeErr := pingerConn.Close(); closeErr != nil { | ||
panic(closeErr) | ||
} | ||
}() | ||
|
||
// Punch a UDP hole for the relayConn by sending a data to the mappedAddr. | ||
// This will trigger a TURN client to generate a permission request to the | ||
// TURN server. After this, packets from the IP address will be accepted by | ||
// the TURN server. | ||
_, err = relayConn.WriteTo([]byte("Hello"), mappedAddr) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Start read-loop on pingerConn | ||
go func() { | ||
buf := make([]byte, 1500) | ||
for { | ||
n, from, pingerErr := pingerConn.ReadFrom(buf) | ||
if pingerErr != nil { | ||
break | ||
} | ||
|
||
msg := string(buf[:n]) | ||
if sentAt, pingerErr := time.Parse(time.RFC3339Nano, msg); pingerErr == nil { | ||
rtt := time.Since(sentAt) | ||
log.Printf("%d bytes from from %s time=%d ms\n", n, from.String(), int(rtt.Seconds()*1000)) | ||
} | ||
} | ||
}() | ||
|
||
// Start read-loop on relayConn | ||
go func() { | ||
buf := make([]byte, 1500) | ||
for { | ||
n, from, readerErr := relayConn.ReadFrom(buf) | ||
if readerErr != nil { | ||
break | ||
} | ||
|
||
// Echo back | ||
if _, readerErr = relayConn.WriteTo(buf[:n], from); readerErr != nil { | ||
break | ||
} | ||
} | ||
}() | ||
|
||
time.Sleep(500 * time.Millisecond) | ||
|
||
// Send 10 packets from relayConn to the echo server | ||
for i := 0; i < 10; i++ { | ||
msg := time.Now().Format(time.RFC3339Nano) | ||
_, err = pingerConn.WriteTo([]byte(msg), relayConn.LocalAddr()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// For simplicity, this example does not wait for the pong (reply). | ||
// Instead, sleep 1 second. | ||
time.Sleep(time.Second) | ||
} | ||
|
||
return nil | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters