...
1
2
3
4
5 package socket
6
7 import (
8 "errors"
9 "net"
10 "os"
11 "syscall"
12 )
13
14
15 type Conn struct {
16 network string
17 c syscall.RawConn
18 }
19
20
21
22 type tcpConn interface {
23 SyscallConn() (syscall.RawConn, error)
24 SetLinger(int) error
25 }
26
27 var _ tcpConn = (*net.TCPConn)(nil)
28
29
30
31 type udpConn interface {
32 SyscallConn() (syscall.RawConn, error)
33 ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *net.UDPAddr, err error)
34 }
35
36 var _ udpConn = (*net.UDPConn)(nil)
37
38
39
40 type ipConn interface {
41 SyscallConn() (syscall.RawConn, error)
42 ReadMsgIP(b, oob []byte) (n, oobn, flags int, addr *net.IPAddr, err error)
43 }
44
45 var _ ipConn = (*net.IPConn)(nil)
46
47
48 func NewConn(c net.Conn) (*Conn, error) {
49 var err error
50 var cc Conn
51 switch c := c.(type) {
52 case tcpConn:
53 cc.network = "tcp"
54 cc.c, err = c.SyscallConn()
55 case udpConn:
56 cc.network = "udp"
57 cc.c, err = c.SyscallConn()
58 case ipConn:
59 cc.network = "ip"
60 cc.c, err = c.SyscallConn()
61 default:
62 return nil, errors.New("unknown connection type")
63 }
64 if err != nil {
65 return nil, err
66 }
67 return &cc, nil
68 }
69
70 func (o *Option) get(c *Conn, b []byte) (int, error) {
71 var operr error
72 var n int
73 fn := func(s uintptr) {
74 n, operr = getsockopt(s, o.Level, o.Name, b)
75 }
76 if err := c.c.Control(fn); err != nil {
77 return 0, err
78 }
79 return n, os.NewSyscallError("getsockopt", operr)
80 }
81
82 func (o *Option) set(c *Conn, b []byte) error {
83 var operr error
84 fn := func(s uintptr) {
85 operr = setsockopt(s, o.Level, o.Name, b)
86 }
87 if err := c.c.Control(fn); err != nil {
88 return err
89 }
90 return os.NewSyscallError("setsockopt", operr)
91 }
92
View as plain text