func (c *SCTPConn) RemoteAddr() net.Addr {
	ptr, n, e := sctpGetpaddrs(c.l.sock, c.id)
	if e != nil {
		return nil
	}
	defer sctpFreepaddrs(ptr)
	return resolveFromRawAddr(ptr, n)
}
RemoteAddr returns the remote network address.
package extnet
import (
	"fmt"
	"io"
	"net"
	"sync"
	"time"
	"unsafe"
)
type SCTPConn struct {
	l  *SCTPListener
	id assocT
	buf, win []byte
	err      error
	m, rm, wm sync.Mutex
	wc        sync.Cond
	wd, rd time.Time
}
func (c *SCTPConn) Read(b []byte) (n int, e error) {
	c.rm.Lock()
	defer c.rm.Unlock()
	c.m.Lock()
	defer c.m.Unlock()
	var t *time.Timer
	if now := time.Now(); !c.rd.IsZero() && now.Before(c.rd) {
		t = time.AfterFunc(c.rd.Sub(now), func() {
			er := &net.OpError{
				Op:     "read",
				Net:    "sctp",
				Source: c.LocalAddr(),
				Addr:   c.RemoteAddr(),
				Err:    &timeoutError{}}
			c.queue(nil, er)
		})
	}
	for {
		if len(c.win) != 0 {
			n = copy(b, c.win)
			c.win = c.win[n:]
			break
		}
		if c.err != nil {
			e = c.err
			if e != io.EOF {
				c.err = nil
			}
			break
		}
		c.wc.Wait()
	}
	if t != nil {
		t.Stop()
	}
	return
}
func (c *SCTPConn) queue(b []byte, e error) error {
	if c.err == io.EOF {
		return c.err
	}
	c.wm.Lock()
	defer c.wm.Unlock()
	if b != nil {
		c.m.Lock()
		defer c.m.Unlock()
		if len(c.win) == 0 {
			c.win = append(c.buf, b...)
		} else {
			c.win = append(c.win, b...)
		}
		c.wc.Signal()
	}
	if e != nil {
		c.m.Lock()
		defer c.m.Unlock()
		c.err = e
		c.wc.Signal()
	}
	return nil
}
func (c *SCTPConn) Write(b []byte) (int, error) {
	buf := make([]byte, len(b))
	copy(buf, b)
	n, e := c.send(buf, c.l.ppid, 0, 0)
	if e != nil {
		e = &net.OpError{
			Op:     "write",
			Net:    "sctp",
			Source: c.LocalAddr(),
			Addr:   c.RemoteAddr(),
			Err:    e}
	}
	return n, e
}
func (c *SCTPConn) WriteToStream(b []byte, s uint16, i uint32) (int, error) {
	buf := make([]byte, len(b))
	copy(buf, b)
	n, e := c.send(buf, i, s, 0)
	if e != nil {
		e = &net.OpError{
			Op:     "write",
			Net:    "sctp",
			Source: c.LocalAddr(),
			Addr:   c.RemoteAddr(),
			Err:    e}
	}
	return n, e
}
func (c *SCTPConn) Close() error {
	_, e := c.send([]byte{}, 0, 0, sctpEoF)
	if e != nil {
		e = &net.OpError{
			Op:     "close",
			Net:    "sctp",
			Source: c.LocalAddr(),
			Addr:   c.RemoteAddr(),
			Err:    e}
	}
	b := make([]byte, 1024)
	for {
		_, eof := c.Read(b)
		if eof == io.EOF {
			break
		}
	}
	return e
}
func (c *SCTPConn) Abort(reason string) error {
	buf := make([]byte, len([]byte(reason)))
	copy(buf, []byte(reason))
	_, e := c.send(buf, 0, 0, sctpAbort)
	if e != nil {
		e = &net.OpError{
			Op:     "abort",
			Net:    "sctp",
			Source: c.LocalAddr(),
			Addr:   c.RemoteAddr(),
			Err:    e}
	}
	return e
}
func (c *SCTPConn) send(b []byte, p uint32, s, f uint16) (int, error) {
	info := sndrcvInfo{}
	if n := time.Now(); !c.wd.IsZero() && n.Before(c.wd) {
		info.timetolive = uint32(c.wd.Sub(n))
	}
	info.stream = s
	info.flags = f | c.l.uo
	info.assocID = c.id
	info.ppid = p
	i, e := sctpSend(c.l.sock, b, &info, 0)
	if Notificator != nil {
		if i < 0 {
			i = 0
		}
		Notificator(&SctpSendData{
			ID:        int(info.assocID),
			Stream:    int(info.stream),
			PPID:      int(info.ppid),
			Unordered: info.flags&sctpUnordered == sctpUnordered,
			Data:      b[:i],
			Err:       e})
	}
	return i, e
}
type SctpSendData struct {
	ID        int
	Stream    int
	PPID      int
	Unordered bool
	Data      []byte
	Err       error
}
func (e *SctpSendData) Error() string {
	if e == nil {
		return "<nil>"
	}
	s, ok := ppidStr[e.PPID]
	if !ok {
		s = "Unassigned"
	}
	uo := ""
	if e.Unordered {
		uo = ", unorderd"
	}
	if e.Err != nil {
		return fmt.Sprintf(
			"send data to association(id=%d, stream=%d, ppid=%s%s) failed, %s: % x",
			e.ID, e.Stream, s, uo, e.Err, e.Data)
	}
	return fmt.Sprintf(
		"send data to association(id=%d, stream=%d, ppid=%s%s): % x",
		e.ID, e.Stream, s, uo, e.Data)
}
func (c *SCTPConn) LocalAddr() net.Addr {
	ptr, n, e := sctpGetladdrs(c.l.sock, c.id)
	if e != nil {
		return nil
	}
	defer sctpFreeladdrs(ptr)
	return resolveFromRawAddr(ptr, n)
}