Look up route for every peer
This commit is contained in:
parent
659106bd6d
commit
0fb14232fa
2
conn.go
2
conn.go
|
@ -123,7 +123,7 @@ func (device *Device) BindUpdate() error {
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
netc := &device.net
|
netc := &device.net
|
||||||
netc.bind, netc.port, err = CreateBind(netc.port)
|
netc.bind, netc.port, err = CreateBind(netc.port, device)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
netc.bind = nil
|
netc.bind = nil
|
||||||
netc.port = 0
|
netc.port = 0
|
||||||
|
|
|
@ -81,7 +81,7 @@ func listenNet(network string, port int) (*net.UDPConn, int, error) {
|
||||||
return conn, uaddr.Port, nil
|
return conn, uaddr.Port, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateBind(uport uint16) (Bind, uint16, error) {
|
func CreateBind(uport uint16, device *Device) (Bind, uint16, error) {
|
||||||
var err error
|
var err error
|
||||||
var bind NativeBind
|
var bind NativeBind
|
||||||
|
|
||||||
|
|
147
conn_linux.go
147
conn_linux.go
|
@ -55,11 +55,10 @@ func (endpoint *NativeEndpoint) dst6() *unix.SockaddrInet6 {
|
||||||
}
|
}
|
||||||
|
|
||||||
type NativeBind struct {
|
type NativeBind struct {
|
||||||
sock4 int
|
sock4 int
|
||||||
sock6 int
|
sock6 int
|
||||||
netlinkSock int
|
netlinkSock int
|
||||||
lastEndpoint *NativeEndpoint
|
lastMark uint32
|
||||||
lastMark uint32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Endpoint = (*NativeEndpoint)(nil)
|
var _ Endpoint = (*NativeEndpoint)(nil)
|
||||||
|
@ -118,7 +117,7 @@ func createNetlinkRouteSocket() (int, error) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateBind(port uint16) (*NativeBind, uint16, error) {
|
func CreateBind(port uint16, device *Device) (*NativeBind, uint16, error) {
|
||||||
var err error
|
var err error
|
||||||
var bind NativeBind
|
var bind NativeBind
|
||||||
|
|
||||||
|
@ -127,7 +126,7 @@ func CreateBind(port uint16) (*NativeBind, uint16, error) {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
go bind.routineRouteListener()
|
go bind.routineRouteListener(device)
|
||||||
|
|
||||||
bind.sock6, port, err = create6(port)
|
bind.sock6, port, err = create6(port)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -171,8 +170,8 @@ func (bind *NativeBind) SetMark(value uint32) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func closeUnblock(fd int) error {
|
func closeUnblock(fd int) error {
|
||||||
// shutdown to unblock readers
|
// shutdown to unblock readers and writers
|
||||||
unix.Shutdown(fd, unix.SHUT_RD)
|
unix.Shutdown(fd, unix.SHUT_RDWR)
|
||||||
return unix.Close(fd)
|
return unix.Close(fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,7 +205,6 @@ func (bind *NativeBind) ReceiveIPv4(buff []byte) (int, Endpoint, error) {
|
||||||
buff,
|
buff,
|
||||||
&end,
|
&end,
|
||||||
)
|
)
|
||||||
bind.lastEndpoint = &end
|
|
||||||
return n, &end, err
|
return n, &end, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,8 +549,8 @@ func receive6(sock int, buff []byte, end *NativeEndpoint) (int, error) {
|
||||||
return size, nil
|
return size, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bind *NativeBind) routineRouteListener() {
|
func (bind *NativeBind) routineRouteListener(device *Device) {
|
||||||
// TODO: this function doesn't lock the endpoint it modifies
|
var reqPeer map[uint32]*Peer
|
||||||
|
|
||||||
for msg := make([]byte, 1<<16); ; {
|
for msg := make([]byte, 1<<16); ; {
|
||||||
msgn, _, _, _, err := unix.Recvmsg(bind.netlinkSock, msg[:], nil, 0)
|
msgn, _, _, _, err := unix.Recvmsg(bind.netlinkSock, msg[:], nil, 0)
|
||||||
|
@ -570,12 +568,7 @@ func (bind *NativeBind) routineRouteListener() {
|
||||||
|
|
||||||
switch hdr.Type {
|
switch hdr.Type {
|
||||||
case unix.RTM_NEWROUTE, unix.RTM_DELROUTE:
|
case unix.RTM_NEWROUTE, unix.RTM_DELROUTE:
|
||||||
|
if hdr.Seq <= MaxPeers {
|
||||||
if bind.lastEndpoint == nil || bind.lastEndpoint.isV6 || bind.lastEndpoint.src4().ifindex == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if hdr.Seq == 0xff {
|
|
||||||
if uint(len(remain)) < uint(hdr.Len) {
|
if uint(len(remain)) < uint(hdr.Len) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -591,54 +584,90 @@ func (bind *NativeBind) routineRouteListener() {
|
||||||
}
|
}
|
||||||
if attrhdr.Type == unix.RTA_OIF && attrhdr.Len == unix.SizeofRtAttr+4 {
|
if attrhdr.Type == unix.RTA_OIF && attrhdr.Len == unix.SizeofRtAttr+4 {
|
||||||
ifidx := *(*uint32)(unsafe.Pointer(&attr[unix.SizeofRtAttr]))
|
ifidx := *(*uint32)(unsafe.Pointer(&attr[unix.SizeofRtAttr]))
|
||||||
if uint32(bind.lastEndpoint.src4().ifindex) != ifidx {
|
if reqPeer == nil {
|
||||||
bind.lastEndpoint.ClearSrc()
|
break
|
||||||
}
|
}
|
||||||
|
peer, ok := reqPeer[hdr.Seq]
|
||||||
|
if !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
peer.mutex.RLock()
|
||||||
|
if peer.endpoint == nil || peer.endpoint.(*NativeEndpoint) == nil {
|
||||||
|
peer.mutex.RUnlock()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if peer.endpoint.(*NativeEndpoint).isV6 || peer.endpoint.(*NativeEndpoint).src4().ifindex == 0 {
|
||||||
|
peer.mutex.RUnlock()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if uint32(peer.endpoint.(*NativeEndpoint).src4().ifindex) == ifidx {
|
||||||
|
peer.mutex.RUnlock()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
peer.mutex.RUnlock()
|
||||||
|
peer.mutex.Lock()
|
||||||
|
peer.endpoint.(*NativeEndpoint).ClearSrc()
|
||||||
|
peer.mutex.Unlock()
|
||||||
}
|
}
|
||||||
attr = attr[attrhdr.Len:]
|
attr = attr[attrhdr.Len:]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
reqPeer = make(map[uint32]*Peer)
|
||||||
nlmsg := struct {
|
go func() {
|
||||||
hdr unix.NlMsghdr
|
device.peers.mutex.RLock()
|
||||||
msg unix.RtMsg
|
i := uint32(1)
|
||||||
dsthdr unix.RtAttr
|
for _, peer := range device.peers.keyMap {
|
||||||
dst [4]byte
|
peer.mutex.RLock()
|
||||||
srchdr unix.RtAttr
|
if peer.endpoint == nil || peer.endpoint.(*NativeEndpoint) == nil {
|
||||||
src [4]byte
|
peer.mutex.RUnlock()
|
||||||
markhdr unix.RtAttr
|
continue
|
||||||
mark uint32
|
}
|
||||||
}{
|
nlmsg := struct {
|
||||||
unix.NlMsghdr{
|
hdr unix.NlMsghdr
|
||||||
Type: uint16(unix.RTM_GETROUTE),
|
msg unix.RtMsg
|
||||||
Flags: unix.NLM_F_REQUEST,
|
dsthdr unix.RtAttr
|
||||||
Seq: 0xff,
|
dst [4]byte
|
||||||
},
|
srchdr unix.RtAttr
|
||||||
unix.RtMsg{
|
src [4]byte
|
||||||
Family: unix.AF_INET,
|
markhdr unix.RtAttr
|
||||||
Dst_len: 32,
|
mark uint32
|
||||||
Src_len: 32,
|
}{
|
||||||
},
|
unix.NlMsghdr{
|
||||||
unix.RtAttr{
|
Type: uint16(unix.RTM_GETROUTE),
|
||||||
Len: 8,
|
Flags: unix.NLM_F_REQUEST,
|
||||||
Type: unix.RTA_DST,
|
Seq: i,
|
||||||
},
|
},
|
||||||
bind.lastEndpoint.dst4().Addr,
|
unix.RtMsg{
|
||||||
unix.RtAttr{
|
Family: unix.AF_INET,
|
||||||
Len: 8,
|
Dst_len: 32,
|
||||||
Type: unix.RTA_SRC,
|
Src_len: 32,
|
||||||
},
|
},
|
||||||
bind.lastEndpoint.src4().src,
|
unix.RtAttr{
|
||||||
unix.RtAttr{
|
Len: 8,
|
||||||
Len: 8,
|
Type: unix.RTA_DST,
|
||||||
Type: 0x10, //unix.RTA_MARK TODO: add this to x/sys/unix
|
},
|
||||||
},
|
peer.endpoint.(*NativeEndpoint).dst4().Addr,
|
||||||
uint32(bind.lastMark),
|
unix.RtAttr{
|
||||||
}
|
Len: 8,
|
||||||
nlmsg.hdr.Len = uint32(unsafe.Sizeof(nlmsg))
|
Type: unix.RTA_SRC,
|
||||||
unix.Write(bind.netlinkSock, (*[unsafe.Sizeof(nlmsg)]byte)(unsafe.Pointer(&nlmsg))[:])
|
},
|
||||||
|
peer.endpoint.(*NativeEndpoint).src4().src,
|
||||||
|
unix.RtAttr{
|
||||||
|
Len: 8,
|
||||||
|
Type: 0x10, //unix.RTA_MARK TODO: add this to x/sys/unix
|
||||||
|
},
|
||||||
|
uint32(bind.lastMark),
|
||||||
|
}
|
||||||
|
nlmsg.hdr.Len = uint32(unsafe.Sizeof(nlmsg))
|
||||||
|
reqPeer[i] = peer
|
||||||
|
peer.mutex.RUnlock()
|
||||||
|
i++
|
||||||
|
unix.Write(bind.netlinkSock, (*[unsafe.Sizeof(nlmsg)]byte)(unsafe.Pointer(&nlmsg))[:])
|
||||||
|
}
|
||||||
|
device.peers.mutex.RUnlock()
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
remain = remain[hdr.Len:]
|
remain = remain[hdr.Len:]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue