// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build linux

package netconfig

// We connect to the Netlink Route socket and parse messages to
// look for network configuration changes.  This is very Linux
// specific, hence the file name.

import (
	"errors"
	"fmt"
	"net"
	"sync"
	"syscall"
	"time"
	"unsafe"

	"v.io/x/lib/vlog"
)

/*
#include <linux/rtnetlink.h>
*/
import "C"

// All rtnetlink attributes start with this header.
type rtAttrHdr C.struct_rtattr

const rtAttrHdrLen = C.sizeof_struct_rtattr

// The address change messages (RTM_NEWADDR, RTM_DELADDR, RTM_GETADDR).
type ifaddrMsgHdr C.struct_ifaddrmsg

const ifaddrMsgHdrLen = C.sizeof_struct_ifaddrmsg

type rtAttribute fmt.Stringer

type rtAddressMessage struct {
	name       string
	hdr        ifaddrMsgHdr
	attributes []rtAttribute
}

// Attribute types (see rtnetlink(7))
type ifaAddress net.IP
type ifaLocal net.IP
type ifaBroadcast net.IP
type ifaAnycast net.IP
type ifaMulticast net.IP
type ifaLabel string
type ifaCacheInfo C.struct_ifa_cacheinfo

const ifaCacheInfoLen = C.sizeof_struct_ifa_cacheinfo

// String routines to make debugging easier.
func (a ifaAddress) String() string   { return "Address=" + net.IP(a).String() }
func (a ifaLocal) String() string     { return "Local=" + net.IP(a).String() }
func (a ifaBroadcast) String() string { return "Braodcast=" + net.IP(a).String() }
func (a ifaAnycast) String() string   { return "Anycast=" + net.IP(a).String() }
func (a ifaMulticast) String() string { return "Anycast=" + net.IP(a).String() }
func (a ifaLabel) String() string     { return "Label=" + string(a) }
func (a ifaCacheInfo) String() string {
	return fmt.Sprintf("CacheInfo[preferred %d valid %d cstamp %d tstamp %d]", a.ifa_prefered, a.ifa_valid, a.cstamp, a.tstamp)
}
func (m *rtAddressMessage) String() string {
	return fmt.Sprintf("%s: index %d %v", m.name, m.hdr.ifa_index, m.attributes)
}

// Address looks for the address attribute in an rtAddressMessage.  If it isn't there, just assume the null address.
func (m *rtAddressMessage) Address() net.IP {
	for _, a := range m.attributes {
		switch a.(type) {
		case ifaAddress:
			return net.IP(a.(ifaAddress))
		}
	}
	return net.IPv4zero
}

func parsertAddressAttribute(b []byte) (rtAttribute, []byte, error) {
	if len(b) == 0 {
		return nil, nil, nil
	}
	if len(b) < rtAttrHdrLen {
		return nil, nil, errors.New("attribute too short")
	}
	ahdr := (*rtAttrHdr)(unsafe.Pointer(&b[0]))
	rounded := ((ahdr.rta_len + 3) / 4) * 4
	if len(b) < int(rounded) {
		return nil, nil, errors.New("attribute too short")
	}
	remaining := b[rounded:]
	b = b[rtAttrHdrLen:ahdr.rta_len]
	switch ahdr.rta_type {
	case C.IFA_ADDRESS:
		return rtAttribute(ifaAddress(net.IP(b))), remaining, nil
	case C.IFA_LOCAL:
		return rtAttribute(ifaLocal(b)), remaining, nil
	case C.IFA_LABEL:
		return rtAttribute(ifaLabel(b)), remaining, nil
	case C.IFA_BROADCAST:
		return rtAttribute(ifaBroadcast(b)), remaining, nil
	case C.IFA_ANYCAST:
		return rtAttribute(ifaAnycast(b)), remaining, nil
	case C.IFA_CACHEINFO:
		if len(b) < ifaCacheInfoLen {
			return nil, nil, errors.New("attribute too short")
		}
		return rtAttribute(ifaCacheInfo(*(*C.struct_ifa_cacheinfo)(unsafe.Pointer(&b[0])))), remaining, nil
	case C.IFA_MULTICAST:
		return rtAttribute(ifaMulticast(b)), remaining, nil
	}
	return nil, remaining, errors.New("unknown attribute")
}

func parsertAddressMessage(nlm syscall.NetlinkMessage) (*rtAddressMessage, error) {
	var name string
	switch nlm.Header.Type {
	case C.RTM_NEWADDR:
		name = "RTM_NEWADDR"
	case C.RTM_DELADDR:
		name = "RTM_DELADDR"
	case C.RTM_GETADDR:
		name = "RTM_GETADDR"
	default:
		return nil, fmt.Errorf("unknown message type")
	}
	if len(nlm.Data) < ifaddrMsgHdrLen {
		return nil, errors.New("bad length")
	}
	m := &rtAddressMessage{name: name, hdr: *(*ifaddrMsgHdr)(unsafe.Pointer(&nlm.Data[0]))}
	b := nlm.Data[ifaddrMsgHdrLen:]
	for {
		var a rtAttribute
		var err error
		a, b, err = parsertAddressAttribute(b)
		if b == nil {
			break
		}
		if err == nil {
			m.attributes = append(m.attributes, a)
		}
	}
	return m, nil
}

// The link change messages (RTM_NEWLINK, RTM_DELLINK, RTM_GETLINK).
type ifInfoMsgHdr C.struct_ifinfomsg

const ifInfoMsgHdrLen = C.sizeof_struct_ifinfomsg

type rtLinkMessage struct {
	name       string
	hdr        ifInfoMsgHdr
	attributes []rtAttribute
}

// Attribute types (see rtnetlink(7))
type iflaAddress []byte
type iflaBroadcast []byte
type iflaIFName string
type iflaMTU uint32
type iflaLink int
type iflaQDisc string
type iflaOperstate int
type iflaStats C.struct_rtnl_link_stats

const iflaStatsLen = C.sizeof_struct_rtnl_link_stats

// String routines to make debugging easier.
func (a iflaAddress) String() string   { return fmt.Sprintf("HWAddress=%v", []byte(a)) }
func (a iflaBroadcast) String() string { return fmt.Sprintf("HWBroadcast=%v", []byte(a)) }
func (a iflaIFName) String() string    { return "Name=" + string(a) }
func (a iflaMTU) String() string       { return fmt.Sprintf("MTU=%d", uint32(a)) }
func (a iflaLink) String() string      { return fmt.Sprintf("Type=%d", int(a)) }
func (a iflaQDisc) String() string     { return "Qdisc=" + string(a) }
func (a iflaStats) String() string {
	return fmt.Sprintf("Stats[rx %d tx %d ...]", a.rx_packets, a.tx_packets)
}
func (a iflaOperstate) String() string { return fmt.Sprintf("Operstate=%d", int(a)) }
func (m *rtLinkMessage) String() string {
	return fmt.Sprintf("%s: index %d %v", m.name, m.hdr.ifi_index, m.attributes)
}

func parseRTLinkAttribute(b []byte) (rtAttribute, []byte, error) {
	if len(b) == 0 {
		return nil, nil, nil
	}
	if len(b) < rtAttrHdrLen {
		return nil, nil, errors.New("attribute too short")
	}
	ahdr := (*rtAttrHdr)(unsafe.Pointer(&b[0]))
	rounded := ((ahdr.rta_len + 3) / 4) * 4
	if len(b) < int(rounded) {
		return nil, nil, errors.New("attribute too short")
	}
	remaining := b[rounded:]
	b = b[rtAttrHdrLen:ahdr.rta_len]
	switch ahdr.rta_type {
	case C.IFLA_ADDRESS:
		return rtAttribute(iflaAddress(b)), remaining, nil
	case C.IFLA_BROADCAST:
		return rtAttribute(iflaBroadcast(b)), remaining, nil
	case C.IFLA_IFNAME:
		return rtAttribute(iflaIFName(string(b))), remaining, nil
	case C.IFLA_MTU:
		return rtAttribute(iflaMTU(*(*C.uint)(unsafe.Pointer(&b[0])))), remaining, nil
	case C.IFLA_LINK:
		return rtAttribute(iflaMTU(*(*C.int)(unsafe.Pointer(&b[0])))), remaining, nil
	case C.IFLA_QDISC:
		return rtAttribute(iflaQDisc(string(b))), remaining, nil
	case C.IFLA_STATS:
		if len(b) < iflaStatsLen {
			return nil, remaining, errors.New("attribute too short")
		}
		return rtAttribute(iflaStats(*(*C.struct_rtnl_link_stats)(unsafe.Pointer(&b[0])))), remaining, nil
	case C.IFLA_OPERSTATE:
		return rtAttribute(iflaOperstate(*(*C.int)(unsafe.Pointer(&b[0])))), remaining, nil
	}
	return nil, remaining, errors.New("unknown attribute")
}

func parsertLinkMessage(nlm syscall.NetlinkMessage) (*rtLinkMessage, error) {
	var name string
	switch nlm.Header.Type {
	case C.RTM_NEWLINK:
		name = "RTM_NEWLINK"
	case C.RTM_DELLINK:
		name = "RTM_DELLINK"
	case C.RTM_GETLINK:
		name = "RTM_GETLINK"
	default:
		return nil, fmt.Errorf("unknown message type")
	}
	if len(nlm.Data) < ifInfoMsgHdrLen {
		return nil, errors.New("bad length")
	}
	m := &rtLinkMessage{name: name, hdr: *(*ifInfoMsgHdr)(unsafe.Pointer(&nlm.Data[0]))}
	b := nlm.Data[ifInfoMsgHdrLen:]
	for {
		var a rtAttribute
		var err error
		a, b, err = parseRTLinkAttribute(b)
		if b == nil {
			break
		}
		if err == nil {
			m.attributes = append(m.attributes, a)
		}
	}
	return m, nil
}

type rtnetlinkWatcher struct {
	sync.Mutex
	t       *time.Timer
	c       chan struct{}
	s       int
	stopped bool
}

func (w *rtnetlinkWatcher) Stop() {
	w.Lock()
	defer w.Unlock()
	if w.stopped {
		return
	}
	w.stopped = true
	syscall.Close(w.s)
}

func (w *rtnetlinkWatcher) Channel() chan struct{} {
	return w.c
}

const (
	GROUPS = C.RTMGRP_LINK | C.RTMGRP_IPV4_IFADDR | C.RTMGRP_IPV4_MROUTE | C.RTMGRP_IPV4_ROUTE | C.RTMGRP_IPV6_IFADDR | C.RTMGRP_IPV6_MROUTE | C.RTMGRP_IPV6_ROUTE | C.RTMGRP_NOTIFY
)

// NewNetConfigWatcher returns a watcher that wakes up anyone
// calling the Wait routine whenever the configuration changes.
func NewNetConfigWatcher() (NetConfigWatcher, error) {
	s, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_ROUTE)
	if err != nil {
		vlog.Infof("netconfig socket failed: %s", err)
		return nil, err
	}

	lsa := &syscall.SockaddrNetlink{Family: syscall.AF_NETLINK, Groups: GROUPS}
	if err := syscall.Bind(s, lsa); err != nil {
		vlog.Infof("netconfig bind failed: %s", err)
		return nil, err
	}

	w := &rtnetlinkWatcher{c: make(chan struct{}, 1), s: s}
	go w.watcher()
	return w, nil
}

func (w *rtnetlinkWatcher) ding() {
	w.Lock()
	defer w.Unlock()
	w.t = nil
	if w.stopped {
		return
	}
	// Don't let us hang in the lock.  The default is safe because the requirement
	// is that the client get a message after the last config change.  Since this is
	// a queued chan, we really don't have to stuff anything in it if there's already
	// something there.
	select {
	case w.c <- struct{}{}:
	default:
	}
}

func (w *rtnetlinkWatcher) watcher() {
	var newAddrs []net.IP
	for {
		rb := make([]byte, 4096)
		nr, _, err := syscall.Recvfrom(w.s, rb, 0)
		if err != nil {
			break
		}
		rb = rb[:nr]
		msgs, err := syscall.ParseNetlinkMessage(rb)
		if err != nil {
			vlog.Infof("ParseNetlinkMessage failed: %s", err)
			continue
		}
	L:
		for _, m := range msgs {
			if am, err := parsertAddressMessage(m); err == nil {
				// NOTE(p): We get continuous NEWADDR messages about some
				// IPv6 addresses in Google corp.  Just ignore duplicate back
				// to back NEWADDRs about the same addresses.
				if am.name == "RTM_NEWADDR" {
					addr := am.Address()
					for _, a := range newAddrs {
						if addr.Equal(a) {
							break L
						}
					}
					newAddrs = append(newAddrs, addr)
				} else {
					newAddrs = nil
				}
			} else if _, err := parsertLinkMessage(m); err == nil {
				newAddrs = nil
			} else {
				continue
			}
			// Changing networks usually spans many seconds and involves
			// multiple network config changes.  We add histeresis by
			// setting an alarm when the first change is detected and
			// not informing the client till the alarm goes off.
			// NOTE(p): I chose 3 seconds because that covers all the
			// events involved in moving from one wifi network to another.
			w.Lock()
			if w.t == nil {
				w.t = time.AfterFunc(3*time.Second, w.ding)
			}
			w.Unlock()
		}
	}

	w.Stop()
	w.Lock()
	close(w.c)
	if w.t != nil {
		w.t.Stop()
	}
	w.Unlock()
}
func toIP(a []byte) (net.IP, error) {
	switch len(a) {
	case 4:
		return net.IPv4(a[0], a[1], a[2], a[3]), nil
	case 16:
		return net.IP(a), nil
	}
	return net.IPv6unspecified, errors.New("unknown ip address len")
}

// IPRoutes returns all kernel known routes.  If defaultOnly is set, only default routes
// are returned.
func GetIPRoutes(defaultOnly bool) []*IPRoute {
	var iproutes []*IPRoute
	rib, err := syscall.NetlinkRIB(syscall.RTM_GETROUTE, syscall.AF_UNSPEC)
	if err != nil {
		vlog.Infof("Couldn't read: %s", err)
		return iproutes
	}
	msgs, err := syscall.ParseNetlinkMessage(rib)
	if err != nil {
		vlog.Infof("Couldn't parse: %s", err)
		return iproutes
	}
L:
	for _, m := range msgs {
		if m.Header.Type != syscall.RTM_NEWROUTE {
			continue
		}
		attrs, err := syscall.ParseNetlinkRouteAttr(&m)
		if err != nil {
			continue
		}
		r := new(IPRoute)
		for _, a := range attrs {
			switch a.Attr.Type {
			case syscall.RTA_DST:
				if r.Net.IP, err = toIP(a.Value[:]); err != nil {
					continue L
				}
			case syscall.RTA_GATEWAY:
				if r.Gateway, err = toIP(a.Value[:]); err != nil {
					continue L
				}
			case syscall.RTA_OIF:
				r.IfcIndex = int(a.Value[0])
			case syscall.RTA_PREFSRC:
				if r.PreferredSource, err = toIP(a.Value[:]); err != nil {
					continue L
				}
			}
		}

		// There is no RTA_DST attribute if destination is a default gateway.
		// Set the destination IP with zero IP, if not set yet.
		if r.Net.IP == nil {
			if r.Gateway == nil {
				continue
			}
			if r.Gateway.To4() != nil {
				r.Net.IP = net.IPv4zero
			} else {
				r.Net.IP = net.IPv6zero
			}
		}

		addrLen := 128
		if r.Net.IP.To4() != nil {
			addrLen = 32
		}

		b := m.Data[:syscall.SizeofRtMsg]
		a := (*syscall.RtMsg)(unsafe.Pointer(&b[0]))
		if int(a.Dst_len) > addrLen {
			continue
		}
		r.Net.Mask = net.CIDRMask(int(a.Dst_len), addrLen)
		if !defaultOnly || IsDefaultIPRoute(r) {
			iproutes = append(iproutes, r)
		}
	}
	return iproutes
}
