summaryrefslogtreecommitdiff
path: root/vendor/github.com/pion/ice/v2/transport.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/pion/ice/v2/transport.go')
-rw-r--r--vendor/github.com/pion/ice/v2/transport.go145
1 files changed, 145 insertions, 0 deletions
diff --git a/vendor/github.com/pion/ice/v2/transport.go b/vendor/github.com/pion/ice/v2/transport.go
new file mode 100644
index 0000000..d1c82ff
--- /dev/null
+++ b/vendor/github.com/pion/ice/v2/transport.go
@@ -0,0 +1,145 @@
+package ice
+
+import (
+ "context"
+ "net"
+ "sync/atomic"
+ "time"
+
+ "github.com/pion/stun"
+)
+
+// Dial connects to the remote agent, acting as the controlling ice agent.
+// Dial blocks until at least one ice candidate pair has successfully connected.
+func (a *Agent) Dial(ctx context.Context, remoteUfrag, remotePwd string) (*Conn, error) {
+ return a.connect(ctx, true, remoteUfrag, remotePwd)
+}
+
+// Accept connects to the remote agent, acting as the controlled ice agent.
+// Accept blocks until at least one ice candidate pair has successfully connected.
+func (a *Agent) Accept(ctx context.Context, remoteUfrag, remotePwd string) (*Conn, error) {
+ return a.connect(ctx, false, remoteUfrag, remotePwd)
+}
+
+// Conn represents the ICE connection.
+// At the moment the lifetime of the Conn is equal to the Agent.
+type Conn struct {
+ bytesReceived uint64
+ bytesSent uint64
+ agent *Agent
+}
+
+// BytesSent returns the number of bytes sent
+func (c *Conn) BytesSent() uint64 {
+ return atomic.LoadUint64(&c.bytesSent)
+}
+
+// BytesReceived returns the number of bytes received
+func (c *Conn) BytesReceived() uint64 {
+ return atomic.LoadUint64(&c.bytesReceived)
+}
+
+func (a *Agent) connect(ctx context.Context, isControlling bool, remoteUfrag, remotePwd string) (*Conn, error) {
+ err := a.ok()
+ if err != nil {
+ return nil, err
+ }
+ err = a.startConnectivityChecks(isControlling, remoteUfrag, remotePwd)
+ if err != nil {
+ return nil, err
+ }
+
+ // block until pair selected
+ select {
+ case <-a.done:
+ return nil, a.getErr()
+ case <-ctx.Done():
+ return nil, ErrCanceledByCaller
+ case <-a.onConnected:
+ }
+
+ return &Conn{
+ agent: a,
+ }, nil
+}
+
+// Read implements the Conn Read method.
+func (c *Conn) Read(p []byte) (int, error) {
+ err := c.agent.ok()
+ if err != nil {
+ return 0, err
+ }
+
+ n, err := c.agent.buffer.Read(p)
+ atomic.AddUint64(&c.bytesReceived, uint64(n))
+ return n, err
+}
+
+// Write implements the Conn Write method.
+func (c *Conn) Write(p []byte) (int, error) {
+ err := c.agent.ok()
+ if err != nil {
+ return 0, err
+ }
+
+ if stun.IsMessage(p) {
+ return 0, errICEWriteSTUNMessage
+ }
+
+ pair := c.agent.getSelectedPair()
+ if pair == nil {
+ if err = c.agent.run(c.agent.context(), func(ctx context.Context, a *Agent) {
+ pair = a.getBestValidCandidatePair()
+ }); err != nil {
+ return 0, err
+ }
+
+ if pair == nil {
+ return 0, err
+ }
+ }
+
+ atomic.AddUint64(&c.bytesSent, uint64(len(p)))
+ return pair.Write(p)
+}
+
+// Close implements the Conn Close method. It is used to close
+// the connection. Any calls to Read and Write will be unblocked and return an error.
+func (c *Conn) Close() error {
+ return c.agent.Close()
+}
+
+// LocalAddr returns the local address of the current selected pair or nil if there is none.
+func (c *Conn) LocalAddr() net.Addr {
+ pair := c.agent.getSelectedPair()
+ if pair == nil {
+ return nil
+ }
+
+ return pair.local.addr()
+}
+
+// RemoteAddr returns the remote address of the current selected pair or nil if there is none.
+func (c *Conn) RemoteAddr() net.Addr {
+ pair := c.agent.getSelectedPair()
+ if pair == nil {
+ return nil
+ }
+
+ return pair.remote.addr()
+}
+
+// SetDeadline is a stub
+func (c *Conn) SetDeadline(t time.Time) error {
+ return nil
+}
+
+// SetReadDeadline is a stub
+func (c *Conn) SetReadDeadline(t time.Time) error {
+ return nil
+}
+
+// SetWriteDeadline is a stub
+func (c *Conn) SetWriteDeadline(t time.Time) error {
+ return nil
+}