-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathpacket_connection.go
74 lines (61 loc) · 1.86 KB
/
packet_connection.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package libzt
import (
"net"
"time"
"fmt"
"errors"
"syscall"
"strconv"
)
type PacketConnection struct {
fd int
localIP net.IP
localPort uint16
}
func (c *PacketConnection) ReadFrom(b []byte) (int, net.Addr, error) {
fmt.Println("ReadFrom")
len, sa, err := syscall.Recvfrom(c.fd, b, 0)
var fromAddr *net.UDPAddr
switch sa := sa.(type) {
case *syscall.SockaddrInet4:
fromAddr = &net.UDPAddr{IP: sa.Addr[0:], Port: sa.Port}
case *syscall.SockaddrInet6:
fromAddr = &net.UDPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: string(sa.ZoneId)}
}
return len, toAddr(fromAddr.IP, uint16(fromAddr.Port)), err
}
func (c *PacketConnection) WriteTo(b []byte, addr net.Addr) (int, error) {
udpAddr, ok := addr.(*net.UDPAddr)
if !ok {
return 0, &net.OpError{Op: "write", Net: "udp6", Source: c.LocalAddr(), Addr: addr, Err: syscall.EINVAL}
}
sa := toSocketAddr(udpAddr)
err := syscall.Sendto(c.fd, b, 0, sa)
if err != nil {
err = &net.OpError{Op: "write", Net: "udp6", Source: c.LocalAddr(), Addr: addr, Err: err}
}
return len(b), err
}
func toSocketAddr(udpAddr *net.UDPAddr) (*syscall.SockaddrInet6) {
zoneId, _ := strconv.Atoi(udpAddr.Zone)
sa := &syscall.SockaddrInet6{Port: udpAddr.Port, ZoneId: uint32(zoneId)}
copy(sa.Addr[:], udpAddr.IP)
return sa
}
func (c *PacketConnection) Close() error {
val := close(c.fd)
if val < 0 {
return errors.New("Error closing socket")
}
return nil
}
func (c *PacketConnection) LocalAddr() net.Addr {
return toAddr(c.localIP, c.localPort)
}
func toAddr(ip net.IP, port uint16) *net.UDPAddr {
addr, _ := net.ResolveUDPAddr("udp6", fmt.Sprintf("[%s]:%d", ip.String(), port))
return addr
}
func (c *PacketConnection) SetDeadline(t time.Time) error { return nil }
func (c *PacketConnection) SetReadDeadline(t time.Time) error { return nil }
func (c *PacketConnection) SetWriteDeadline(t time.Time) error { return nil }