2017-08-11 14:18:20 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2017-09-24 19:35:25 +00:00
|
|
|
"errors"
|
2017-08-11 14:18:20 +00:00
|
|
|
"net"
|
|
|
|
)
|
|
|
|
|
2017-09-24 19:35:25 +00:00
|
|
|
func parseEndpoint(s string) (*net.UDPAddr, error) {
|
|
|
|
|
|
|
|
// ensure that the host is an IP address
|
|
|
|
|
|
|
|
host, _, err := net.SplitHostPort(s)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if ip := net.ParseIP(host); ip == nil {
|
|
|
|
return nil, errors.New("Failed to parse IP address: " + host)
|
|
|
|
}
|
|
|
|
|
|
|
|
// parse address and port
|
|
|
|
|
|
|
|
addr, err := net.ResolveUDPAddr("udp", s)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return addr, err
|
|
|
|
}
|
|
|
|
|
2017-10-07 20:35:23 +00:00
|
|
|
func ListenerClose(l *Listener) (err error) {
|
|
|
|
if l.active {
|
|
|
|
err = CloseIPv4Socket(l.sock)
|
|
|
|
l.active = false
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Listener) Init() {
|
|
|
|
l.update = make(chan struct{}, 1)
|
|
|
|
ListenerClose(l)
|
|
|
|
}
|
|
|
|
|
|
|
|
func ListeningUpdate(device *Device) error {
|
2017-08-11 14:18:20 +00:00
|
|
|
netc := &device.net
|
|
|
|
netc.mutex.Lock()
|
2017-08-17 10:58:18 +00:00
|
|
|
defer netc.mutex.Unlock()
|
2017-08-11 14:18:20 +00:00
|
|
|
|
2017-10-07 20:35:23 +00:00
|
|
|
// close existing sockets
|
2017-08-11 14:18:20 +00:00
|
|
|
|
2017-10-07 20:35:23 +00:00
|
|
|
if err := ListenerClose(&netc.ipv4); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-09-26 13:24:18 +00:00
|
|
|
|
2017-10-07 20:35:23 +00:00
|
|
|
if err := ListenerClose(&netc.ipv6); err != nil {
|
|
|
|
return err
|
2017-08-11 14:18:20 +00:00
|
|
|
}
|
|
|
|
|
2017-10-07 20:35:23 +00:00
|
|
|
// open new sockets
|
2017-08-11 14:18:20 +00:00
|
|
|
|
|
|
|
if device.tun.isUp.Get() {
|
2017-08-17 10:58:18 +00:00
|
|
|
|
2017-10-07 20:35:23 +00:00
|
|
|
// listen on IPv4
|
|
|
|
|
|
|
|
{
|
|
|
|
list := &netc.ipv6
|
|
|
|
sock, port, err := CreateIPv4Socket(netc.port)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
netc.port = port
|
|
|
|
list.sock = sock
|
|
|
|
list.active = true
|
|
|
|
|
|
|
|
if err := SetMark(list.sock, netc.fwmark); err != nil {
|
|
|
|
ListenerClose(list)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
signalSend(list.update)
|
2017-08-11 14:18:20 +00:00
|
|
|
}
|
2017-08-17 10:58:18 +00:00
|
|
|
|
2017-10-07 20:35:23 +00:00
|
|
|
// listen on IPv6
|
|
|
|
|
|
|
|
{
|
|
|
|
list := &netc.ipv6
|
|
|
|
sock, port, err := CreateIPv6Socket(netc.port)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
netc.port = port
|
|
|
|
list.sock = sock
|
|
|
|
list.active = true
|
|
|
|
|
|
|
|
if err := SetMark(list.sock, netc.fwmark); err != nil {
|
|
|
|
ListenerClose(list)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
signalSend(list.update)
|
2017-08-22 15:22:45 +00:00
|
|
|
}
|
|
|
|
|
2017-10-07 20:35:23 +00:00
|
|
|
// TODO: clear endpoint caches
|
2017-08-11 14:18:20 +00:00
|
|
|
}
|
|
|
|
|
2017-08-17 10:58:18 +00:00
|
|
|
return nil
|
2017-08-11 14:18:20 +00:00
|
|
|
}
|
|
|
|
|
2017-10-07 20:35:23 +00:00
|
|
|
func ListeningClose(device *Device) error {
|
2017-08-11 14:18:20 +00:00
|
|
|
netc := &device.net
|
|
|
|
netc.mutex.Lock()
|
2017-10-07 20:35:23 +00:00
|
|
|
defer netc.mutex.Unlock()
|
|
|
|
|
|
|
|
if err := ListenerClose(&netc.ipv4); err != nil {
|
|
|
|
return err
|
2017-08-11 14:18:20 +00:00
|
|
|
}
|
2017-10-07 20:35:23 +00:00
|
|
|
signalSend(netc.ipv4.update)
|
|
|
|
|
|
|
|
if err := ListenerClose(&netc.ipv6); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
signalSend(netc.ipv6.update)
|
|
|
|
|
|
|
|
return nil
|
2017-08-11 14:18:20 +00:00
|
|
|
}
|