package ice
import (
"context"
"net"
"sync/atomic"
"time"
"github.com/pion/stun/v3"
)
func (a *Agent ) Dial (ctx context .Context , remoteUfrag , remotePwd string ) (*Conn , error ) {
return a .connect (ctx , true , remoteUfrag , remotePwd )
}
func (a *Agent ) Accept (ctx context .Context , remoteUfrag , remotePwd string ) (*Conn , error ) {
return a .connect (ctx , false , remoteUfrag , remotePwd )
}
type Conn struct {
bytesReceived uint64
bytesSent uint64
agent *Agent
}
func (c *Conn ) BytesSent () uint64 {
return atomic .LoadUint64 (&c .bytesSent )
}
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 .loop .Err ()
if err != nil {
return nil , err
}
err = a .startConnectivityChecks (isControlling , remoteUfrag , remotePwd )
if err != nil {
return nil , err
}
select {
case <- a .loop .Done ():
return nil , a .loop .Err ()
case <- ctx .Done ():
return nil , ErrCanceledByCaller
case <- a .onConnected :
}
return &Conn {
agent : a ,
}, nil
}
func (c *Conn ) Read (p []byte ) (int , error ) {
err := c .agent .loop .Err ()
if err != nil {
return 0 , err
}
n , err := c .agent .buf .Read (p )
atomic .AddUint64 (&c .bytesReceived , uint64 (n ))
return n , err
}
func (c *Conn ) Write (packet []byte ) (int , error ) {
err := c .agent .loop .Err ()
if err != nil {
return 0 , err
}
if stun .IsMessage (packet ) {
return 0 , errWriteSTUNMessageToIceConn
}
pair := c .agent .getSelectedPair ()
if pair == nil {
if err = c .agent .loop .Run (c .agent .loop , func (_ context .Context ) {
pair = c .agent .getBestValidCandidatePair ()
}); err != nil {
return 0 , err
}
if pair == nil {
return 0 , err
}
}
atomic .AddUint64 (&c .bytesSent , uint64 (len (packet )))
return pair .Write (packet )
}
func (c *Conn ) Close () error {
return c .agent .Close ()
}
func (c *Conn ) LocalAddr () net .Addr {
pair := c .agent .getSelectedPair ()
if pair == nil {
return nil
}
return pair .Local .addr ()
}
func (c *Conn ) RemoteAddr () net .Addr {
pair := c .agent .getSelectedPair ()
if pair == nil {
return nil
}
return pair .Remote .addr ()
}
func (c *Conn ) SetDeadline (time .Time ) error {
return nil
}
func (c *Conn ) SetReadDeadline (time .Time ) error {
return nil
}
func (c *Conn ) SetWriteDeadline (time .Time ) error {
return nil
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .