Complete first alpha version
This commit is contained in:
@@ -17,8 +17,11 @@ var (
|
||||
func cleaner() {
|
||||
for {
|
||||
time.Sleep(cleanerTickDuration)
|
||||
|
||||
cleanLinks()
|
||||
time.Sleep(10 * time.Second)
|
||||
cleanConnections()
|
||||
time.Sleep(10 * time.Second)
|
||||
cleanProcesses()
|
||||
}
|
||||
}
|
||||
@@ -26,18 +29,21 @@ func cleaner() {
|
||||
func cleanLinks() {
|
||||
activeIDs := process.GetActiveConnectionIDs()
|
||||
|
||||
dataLock.Lock()
|
||||
defer dataLock.Lock()
|
||||
|
||||
now := time.Now().Unix()
|
||||
deleteOlderThan := time.Now().Add(-deadLinksTimeout).Unix()
|
||||
|
||||
linksLock.RLock()
|
||||
defer linksLock.RUnlock()
|
||||
|
||||
var found bool
|
||||
for key, link := range links {
|
||||
|
||||
// delete dead links
|
||||
if link.Ended > 0 && link.Ended < deleteOlderThan {
|
||||
link.Delete()
|
||||
link.Lock()
|
||||
deleteThis := link.Ended > 0 && link.Ended < deleteOlderThan
|
||||
link.Unlock()
|
||||
if deleteThis {
|
||||
go link.Delete()
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -53,21 +59,23 @@ func cleanLinks() {
|
||||
// mark end time
|
||||
if !found {
|
||||
link.Ended = now
|
||||
link.Save()
|
||||
go link.Save()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func cleanConnections() {
|
||||
dataLock.Lock()
|
||||
defer dataLock.Lock()
|
||||
connectionsLock.RLock()
|
||||
defer connectionsLock.RUnlock()
|
||||
|
||||
threshold := time.Now().Add(-thresholdDuration).Unix()
|
||||
for _, conn := range connections {
|
||||
conn.Lock()
|
||||
if conn.FirstLinkEstablished < threshold && conn.LinkCount == 0 {
|
||||
conn.Delete()
|
||||
go conn.Delete()
|
||||
}
|
||||
conn.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
|
||||
"github.com/Safing/portbase/database/record"
|
||||
"github.com/Safing/portmaster/intel"
|
||||
"github.com/Safing/portmaster/network/netutils"
|
||||
"github.com/Safing/portmaster/network/packet"
|
||||
"github.com/Safing/portmaster/process"
|
||||
)
|
||||
@@ -35,17 +36,28 @@ type Connection struct {
|
||||
|
||||
// Process returns the process that owns the connection.
|
||||
func (conn *Connection) Process() *process.Process {
|
||||
conn.Lock()
|
||||
defer conn.Unlock()
|
||||
|
||||
return conn.process
|
||||
}
|
||||
|
||||
// GetVerdict returns the current verdict.
|
||||
func (conn *Connection) GetVerdict() Verdict {
|
||||
conn.Lock()
|
||||
defer conn.Unlock()
|
||||
|
||||
return conn.Verdict
|
||||
}
|
||||
|
||||
// Accept accepts the connection and adds the given reason.
|
||||
func (conn *Link) Accept(reason string) {
|
||||
func (conn *Connection) Accept(reason string) {
|
||||
conn.AddReason(reason)
|
||||
conn.UpdateVerdict(ACCEPT)
|
||||
}
|
||||
|
||||
// Deny blocks or drops the connection depending on the connection direction and adds the given reason.
|
||||
func (conn *Link) Deny(reason string) {
|
||||
func (conn *Connection) Deny(reason string) {
|
||||
if conn.Direction {
|
||||
conn.Drop(reason)
|
||||
} else {
|
||||
@@ -54,13 +66,13 @@ func (conn *Link) Deny(reason string) {
|
||||
}
|
||||
|
||||
// Block blocks the connection and adds the given reason.
|
||||
func (conn *Link) Block(reason string) {
|
||||
func (conn *Connection) Block(reason string) {
|
||||
conn.AddReason(reason)
|
||||
conn.UpdateVerdict(BLOCK)
|
||||
}
|
||||
|
||||
// Drop drops the connection and adds the given reason.
|
||||
func (conn *Link) Drop(reason string) {
|
||||
func (conn *Connection) Drop(reason string) {
|
||||
conn.AddReason(reason)
|
||||
conn.UpdateVerdict(DROP)
|
||||
}
|
||||
@@ -72,7 +84,7 @@ func (conn *Connection) UpdateVerdict(newVerdict Verdict) {
|
||||
|
||||
if newVerdict > conn.Verdict {
|
||||
conn.Verdict = newVerdict
|
||||
conn.Save()
|
||||
go conn.Save()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,13 +115,13 @@ func GetConnectionByFirstPacket(pkt packet.Packet) (*Connection, error) {
|
||||
// Incoming
|
||||
if direction {
|
||||
switch netutils.ClassifyIP(pkt.GetIPHeader().Src) {
|
||||
case HostLocal:
|
||||
case netutils.HostLocal:
|
||||
domain = IncomingHost
|
||||
case LinkLocal, SiteLocal, LocalMulticast:
|
||||
case netutils.LinkLocal, netutils.SiteLocal, netutils.LocalMulticast:
|
||||
domain = IncomingLAN
|
||||
case Global, GlobalMulticast:
|
||||
case netutils.Global, netutils.GlobalMulticast:
|
||||
domain = IncomingInternet
|
||||
case Invalid:
|
||||
case netutils.Invalid:
|
||||
domain = IncomingInvalid
|
||||
}
|
||||
|
||||
@@ -135,13 +147,13 @@ func GetConnectionByFirstPacket(pkt packet.Packet) (*Connection, error) {
|
||||
// if no domain could be found, it must be a direct connection
|
||||
|
||||
switch netutils.ClassifyIP(pkt.GetIPHeader().Dst) {
|
||||
case HostLocal:
|
||||
case netutils.HostLocal:
|
||||
domain = PeerHost
|
||||
case LinkLocal, SiteLocal, LocalMulticast:
|
||||
case netutils.LinkLocal, netutils.SiteLocal, netutils.LocalMulticast:
|
||||
domain = PeerLAN
|
||||
case Global, GlobalMulticast:
|
||||
case netutils.Global, netutils.GlobalMulticast:
|
||||
domain = PeerInternet
|
||||
case Invalid:
|
||||
case netutils.Invalid:
|
||||
domain = PeerInvalid
|
||||
}
|
||||
|
||||
@@ -205,8 +217,8 @@ func GetConnectionByDNSRequest(ip net.IP, port uint16, fqdn string) (*Connection
|
||||
|
||||
// GetConnection fetches a connection object from the internal storage.
|
||||
func GetConnection(pid int, domain string) (conn *Connection, ok bool) {
|
||||
dataLock.RLock()
|
||||
defer dataLock.RUnlock()
|
||||
connectionsLock.RLock()
|
||||
defer connectionsLock.RUnlock()
|
||||
conn, ok = connections[fmt.Sprintf("%d/%s", pid, domain)]
|
||||
return
|
||||
}
|
||||
@@ -217,58 +229,63 @@ func (conn *Connection) makeKey() string {
|
||||
|
||||
// Save saves the connection object in the storage and propagates the change.
|
||||
func (conn *Connection) Save() error {
|
||||
conn.Lock()
|
||||
defer conn.Unlock()
|
||||
|
||||
if conn.process == nil {
|
||||
return errors.New("cannot save connection without process")
|
||||
}
|
||||
|
||||
if conn.DatabaseKey() == "" {
|
||||
if !conn.KeyIsSet() {
|
||||
conn.SetKey(fmt.Sprintf("network:tree/%d/%s", conn.process.Pid, conn.Domain))
|
||||
conn.CreateMeta()
|
||||
}
|
||||
|
||||
key := conn.makeKey()
|
||||
dataLock.RLock()
|
||||
connectionsLock.RLock()
|
||||
_, ok := connections[key]
|
||||
dataLock.RUnlock()
|
||||
connectionsLock.RUnlock()
|
||||
|
||||
if !ok {
|
||||
dataLock.Lock()
|
||||
connectionsLock.Lock()
|
||||
connections[key] = conn
|
||||
dataLock.Unlock()
|
||||
connectionsLock.Unlock()
|
||||
}
|
||||
|
||||
dbController.PushUpdate(conn)
|
||||
go dbController.PushUpdate(conn)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete deletes a connection from the storage and propagates the change.
|
||||
func (conn *Connection) Delete() {
|
||||
dataLock.Lock()
|
||||
defer dataLock.Unlock()
|
||||
delete(connections, conn.makeKey())
|
||||
conn.Lock()
|
||||
defer conn.Lock()
|
||||
defer conn.Unlock()
|
||||
|
||||
connectionsLock.Lock()
|
||||
delete(connections, conn.makeKey())
|
||||
connectionsLock.Unlock()
|
||||
|
||||
conn.Meta().Delete()
|
||||
dbController.PushUpdate(conn)
|
||||
go dbController.PushUpdate(conn)
|
||||
conn.process.RemoveConnection()
|
||||
}
|
||||
|
||||
// AddLink applies the connection to the link and increases sets counter and timestamps.
|
||||
func (conn *Connection) AddLink(link *Link) {
|
||||
link.Lock()
|
||||
defer link.Unlock()
|
||||
link.connection = conn
|
||||
link.Verdict = conn.Verdict
|
||||
link.Inspect = conn.Inspect
|
||||
link.Unlock()
|
||||
link.Save()
|
||||
|
||||
conn.Lock()
|
||||
defer conn.Unlock()
|
||||
conn.LinkCount++
|
||||
conn.LastLinkEstablished = time.Now().Unix()
|
||||
if conn.FirstLinkEstablished == 0 {
|
||||
conn.FirstLinkEstablished = conn.LastLinkEstablished
|
||||
}
|
||||
conn.Unlock()
|
||||
conn.Save()
|
||||
}
|
||||
|
||||
@@ -276,6 +293,7 @@ func (conn *Connection) AddLink(link *Link) {
|
||||
func (conn *Connection) RemoveLink() {
|
||||
conn.Lock()
|
||||
defer conn.Unlock()
|
||||
|
||||
if conn.LinkCount > 0 {
|
||||
conn.LinkCount--
|
||||
}
|
||||
@@ -283,13 +301,16 @@ func (conn *Connection) RemoveLink() {
|
||||
|
||||
// String returns a string representation of Connection.
|
||||
func (conn *Connection) String() string {
|
||||
conn.Lock()
|
||||
defer conn.Unlock()
|
||||
|
||||
switch conn.Domain {
|
||||
case "I":
|
||||
case IncomingHost, IncomingLAN, IncomingInternet, IncomingInvalid:
|
||||
if conn.process == nil {
|
||||
return "? <- *"
|
||||
}
|
||||
return fmt.Sprintf("%s <- *", conn.process.String())
|
||||
case "D":
|
||||
case PeerHost, PeerLAN, PeerInternet, PeerInvalid:
|
||||
if conn.process == nil {
|
||||
return "? -> *"
|
||||
}
|
||||
|
||||
@@ -14,9 +14,10 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
links map[string]*Link
|
||||
connections map[string]*Connection
|
||||
dataLock sync.RWMutex
|
||||
links = make(map[string]*Link)
|
||||
linksLock sync.RWMutex
|
||||
connections = make(map[string]*Connection)
|
||||
connectionsLock sync.RWMutex
|
||||
|
||||
dbController *database.Controller
|
||||
)
|
||||
@@ -29,9 +30,6 @@ type StorageInterface struct {
|
||||
// Get returns a database record.
|
||||
func (s *StorageInterface) Get(key string) (record.Record, error) {
|
||||
|
||||
dataLock.RLock()
|
||||
defer dataLock.RUnlock()
|
||||
|
||||
splitted := strings.Split(key, "/")
|
||||
switch splitted[0] {
|
||||
case "tree":
|
||||
@@ -45,11 +43,15 @@ func (s *StorageInterface) Get(key string) (record.Record, error) {
|
||||
}
|
||||
}
|
||||
case 3:
|
||||
connectionsLock.RLock()
|
||||
defer connectionsLock.RUnlock()
|
||||
conn, ok := connections[splitted[2]]
|
||||
if ok {
|
||||
return conn, nil
|
||||
}
|
||||
case 4:
|
||||
linksLock.RLock()
|
||||
defer linksLock.RUnlock()
|
||||
link, ok := links[splitted[3]]
|
||||
if ok {
|
||||
return link, nil
|
||||
@@ -77,22 +79,23 @@ func (s *StorageInterface) processQuery(q *query.Query, it *iterator.Iterator) {
|
||||
}
|
||||
}
|
||||
|
||||
dataLock.RLock()
|
||||
defer dataLock.RUnlock()
|
||||
|
||||
// connections
|
||||
connectionsLock.RLock()
|
||||
for _, conn := range connections {
|
||||
if strings.HasPrefix(conn.DatabaseKey(), q.DatabaseKeyPrefix()) {
|
||||
it.Next <- conn
|
||||
}
|
||||
}
|
||||
connectionsLock.RUnlock()
|
||||
|
||||
// links
|
||||
linksLock.RLock()
|
||||
for _, link := range links {
|
||||
if strings.HasPrefix(link.DatabaseKey(), q.DatabaseKeyPrefix()) {
|
||||
it.Next <- link
|
||||
}
|
||||
}
|
||||
linksLock.RUnlock()
|
||||
|
||||
it.Finish(nil)
|
||||
}
|
||||
|
||||
@@ -24,6 +24,9 @@ func getNameserversFromDbus() ([]Nameserver, error) {
|
||||
var nameservers []Nameserver
|
||||
var err error
|
||||
|
||||
dbusConnLock.Lock()
|
||||
defer dbusConnLock.Unlock()
|
||||
|
||||
if dbusConn == nil {
|
||||
dbusConn, err = dbus.SystemBus()
|
||||
}
|
||||
@@ -158,6 +161,9 @@ func getNameserversFromDbus() ([]Nameserver, error) {
|
||||
func getConnectivityStateFromDbus() (uint8, error) {
|
||||
var err error
|
||||
|
||||
dbusConnLock.Lock()
|
||||
defer dbusConnLock.Unlock()
|
||||
|
||||
if dbusConn == nil {
|
||||
dbusConn, err = dbus.SystemBus()
|
||||
}
|
||||
|
||||
128
network/link.go
128
network/link.go
@@ -46,16 +46,33 @@ type Link struct {
|
||||
|
||||
// Connection returns the Connection the Link is part of
|
||||
func (link *Link) Connection() *Connection {
|
||||
link.Lock()
|
||||
defer link.Unlock()
|
||||
|
||||
return link.connection
|
||||
}
|
||||
|
||||
// GetVerdict returns the current verdict.
|
||||
func (link *Link) GetVerdict() Verdict {
|
||||
link.Lock()
|
||||
defer link.Unlock()
|
||||
|
||||
return link.Verdict
|
||||
}
|
||||
|
||||
// FirewallHandlerIsSet returns whether a firewall handler is set or not
|
||||
func (link *Link) FirewallHandlerIsSet() bool {
|
||||
link.Lock()
|
||||
defer link.Unlock()
|
||||
|
||||
return link.firewallHandler != nil
|
||||
}
|
||||
|
||||
// SetFirewallHandler sets the firewall handler for this link
|
||||
func (link *Link) SetFirewallHandler(handler FirewallHandler) {
|
||||
link.Lock()
|
||||
defer link.Unlock()
|
||||
|
||||
if link.firewallHandler == nil {
|
||||
link.firewallHandler = handler
|
||||
link.pktQueue = make(chan packet.Packet, 1000)
|
||||
@@ -67,16 +84,22 @@ func (link *Link) SetFirewallHandler(handler FirewallHandler) {
|
||||
|
||||
// StopFirewallHandler unsets the firewall handler
|
||||
func (link *Link) StopFirewallHandler() {
|
||||
link.Lock()
|
||||
link.firewallHandler = nil
|
||||
link.Unlock()
|
||||
link.pktQueue <- nil
|
||||
}
|
||||
|
||||
// HandlePacket queues packet of Link for handling
|
||||
func (link *Link) HandlePacket(pkt packet.Packet) {
|
||||
link.Lock()
|
||||
defer link.Unlock()
|
||||
|
||||
if link.firewallHandler != nil {
|
||||
link.pktQueue <- pkt
|
||||
return
|
||||
}
|
||||
log.Criticalf("network: link %s does not have a firewallHandler (maybe it's a copy), dropping packet", link)
|
||||
log.Criticalf("network: link %s does not have a firewallHandler, dropping packet", link)
|
||||
pkt.Drop()
|
||||
}
|
||||
|
||||
@@ -88,7 +111,7 @@ func (link *Link) Accept(reason string) {
|
||||
|
||||
// Deny blocks or drops the link depending on the connection direction and adds the given reason.
|
||||
func (link *Link) Deny(reason string) {
|
||||
if link.connection.Direction {
|
||||
if link.connection != nil && link.connection.Direction {
|
||||
link.Drop(reason)
|
||||
} else {
|
||||
link.Block(reason)
|
||||
@@ -107,6 +130,17 @@ func (link *Link) Drop(reason string) {
|
||||
link.UpdateVerdict(DROP)
|
||||
}
|
||||
|
||||
// RerouteToNameserver reroutes the link to the portmaster nameserver.
|
||||
func (link *Link) RerouteToNameserver() {
|
||||
link.UpdateVerdict(RerouteToNameserver)
|
||||
}
|
||||
|
||||
// RerouteToTunnel reroutes the link to the tunnel entrypoint and adds the given reason for accepting the connection.
|
||||
func (link *Link) RerouteToTunnel(reason string) {
|
||||
link.AddReason(reason)
|
||||
link.UpdateVerdict(RerouteToTunnel)
|
||||
}
|
||||
|
||||
// UpdateVerdict sets a new verdict for this link, making sure it does not interfere with previous verdicts
|
||||
func (link *Link) UpdateVerdict(newVerdict Verdict) {
|
||||
link.Lock()
|
||||
@@ -114,7 +148,7 @@ func (link *Link) UpdateVerdict(newVerdict Verdict) {
|
||||
|
||||
if newVerdict > link.Verdict {
|
||||
link.Verdict = newVerdict
|
||||
link.Save()
|
||||
go link.Save()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,54 +172,103 @@ func (link *Link) packetHandler() {
|
||||
for {
|
||||
pkt := <-link.pktQueue
|
||||
if pkt == nil {
|
||||
break
|
||||
return
|
||||
}
|
||||
link.Lock()
|
||||
fwH := link.firewallHandler
|
||||
link.Unlock()
|
||||
if fwH != nil {
|
||||
fwH(pkt, link)
|
||||
} else {
|
||||
link.ApplyVerdict(pkt)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ApplyVerdict appies the link verdict to a packet.
|
||||
func (link *Link) ApplyVerdict(pkt packet.Packet) {
|
||||
link.Lock()
|
||||
defer link.Unlock()
|
||||
|
||||
if link.VerdictPermanent {
|
||||
switch link.Verdict {
|
||||
case ACCEPT:
|
||||
pkt.PermanentAccept()
|
||||
case BLOCK:
|
||||
pkt.PermanentBlock()
|
||||
case DROP:
|
||||
pkt.PermanentDrop()
|
||||
case RerouteToNameserver:
|
||||
pkt.RerouteToNameserver()
|
||||
case RerouteToTunnel:
|
||||
pkt.RerouteToTunnel()
|
||||
default:
|
||||
pkt.Drop()
|
||||
}
|
||||
} else {
|
||||
switch link.Verdict {
|
||||
case ACCEPT:
|
||||
pkt.Accept()
|
||||
case BLOCK:
|
||||
pkt.Block()
|
||||
case DROP:
|
||||
pkt.Drop()
|
||||
case RerouteToNameserver:
|
||||
pkt.RerouteToNameserver()
|
||||
case RerouteToTunnel:
|
||||
pkt.RerouteToTunnel()
|
||||
default:
|
||||
pkt.Drop()
|
||||
}
|
||||
link.firewallHandler(pkt, link)
|
||||
}
|
||||
link.firewallHandler = nil
|
||||
}
|
||||
|
||||
// Save saves the link object in the storage and propagates the change.
|
||||
func (link *Link) Save() error {
|
||||
link.Lock()
|
||||
defer link.Unlock()
|
||||
|
||||
if link.connection == nil {
|
||||
return errors.New("cannot save link without connection")
|
||||
}
|
||||
|
||||
if link.DatabaseKey() == "" {
|
||||
if !link.KeyIsSet() {
|
||||
link.SetKey(fmt.Sprintf("network:tree/%d/%s/%s", link.connection.Process().Pid, link.connection.Domain, link.ID))
|
||||
link.CreateMeta()
|
||||
}
|
||||
|
||||
dataLock.RLock()
|
||||
linksLock.RLock()
|
||||
_, ok := links[link.ID]
|
||||
dataLock.RUnlock()
|
||||
linksLock.RUnlock()
|
||||
|
||||
if !ok {
|
||||
dataLock.Lock()
|
||||
linksLock.Lock()
|
||||
links[link.ID] = link
|
||||
dataLock.Unlock()
|
||||
linksLock.Unlock()
|
||||
}
|
||||
|
||||
dbController.PushUpdate(link)
|
||||
go dbController.PushUpdate(link)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete deletes a link from the storage and propagates the change.
|
||||
func (link *Link) Delete() {
|
||||
dataLock.Lock()
|
||||
defer dataLock.Unlock()
|
||||
delete(links, link.ID)
|
||||
link.Lock()
|
||||
defer link.Lock()
|
||||
defer link.Unlock()
|
||||
|
||||
linksLock.Lock()
|
||||
delete(links, link.ID)
|
||||
linksLock.Unlock()
|
||||
|
||||
link.Meta().Delete()
|
||||
dbController.PushUpdate(link)
|
||||
go dbController.PushUpdate(link)
|
||||
link.connection.RemoveLink()
|
||||
}
|
||||
|
||||
// GetLink fetches a Link from the database from the default namespace for this object
|
||||
func GetLink(id string) (*Link, bool) {
|
||||
dataLock.RLock()
|
||||
defer dataLock.RUnlock()
|
||||
linksLock.RLock()
|
||||
defer linksLock.RUnlock()
|
||||
|
||||
link, ok := links[id]
|
||||
return link, ok
|
||||
@@ -215,6 +298,7 @@ func CreateLinkFromPacket(pkt packet.Packet) *Link {
|
||||
func (link *Link) GetActiveInspectors() []bool {
|
||||
link.Lock()
|
||||
defer link.Unlock()
|
||||
|
||||
return link.activeInspectors
|
||||
}
|
||||
|
||||
@@ -222,6 +306,7 @@ func (link *Link) GetActiveInspectors() []bool {
|
||||
func (link *Link) SetActiveInspectors(new []bool) {
|
||||
link.Lock()
|
||||
defer link.Unlock()
|
||||
|
||||
link.activeInspectors = new
|
||||
}
|
||||
|
||||
@@ -229,6 +314,7 @@ func (link *Link) SetActiveInspectors(new []bool) {
|
||||
func (link *Link) GetInspectorData() map[uint8]interface{} {
|
||||
link.Lock()
|
||||
defer link.Unlock()
|
||||
|
||||
return link.inspectorData
|
||||
}
|
||||
|
||||
@@ -236,11 +322,15 @@ func (link *Link) GetInspectorData() map[uint8]interface{} {
|
||||
func (link *Link) SetInspectorData(new map[uint8]interface{}) {
|
||||
link.Lock()
|
||||
defer link.Unlock()
|
||||
|
||||
link.inspectorData = new
|
||||
}
|
||||
|
||||
// String returns a string representation of Link.
|
||||
func (link *Link) String() string {
|
||||
link.Lock()
|
||||
defer link.Unlock()
|
||||
|
||||
if link.connection == nil {
|
||||
return fmt.Sprintf("? <-> %s", link.RemoteAddress)
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ const (
|
||||
Invalid
|
||||
)
|
||||
|
||||
// ClassifyAddress returns the classification for the given IP address.
|
||||
func ClassifyAddress(ip net.IP) int8 {
|
||||
// ClassifyIP returns the classification for the given IP address.
|
||||
func ClassifyIP(ip net.IP) int8 {
|
||||
if ip4 := ip.To4(); ip4 != nil {
|
||||
// IPv4
|
||||
switch {
|
||||
@@ -73,12 +73,12 @@ func ClassifyAddress(ip net.IP) int8 {
|
||||
|
||||
// IPIsLocalhost returns whether the IP refers to the host itself.
|
||||
func IPIsLocalhost(ip net.IP) bool {
|
||||
return ClassifyAddress(ip) == HostLocal
|
||||
return ClassifyIP(ip) == HostLocal
|
||||
}
|
||||
|
||||
// IPIsLAN returns true if the given IP is a site-local or link-local address.
|
||||
func IPIsLAN(ip net.IP) bool {
|
||||
switch ClassifyAddress(ip) {
|
||||
switch ClassifyIP(ip) {
|
||||
case SiteLocal:
|
||||
return true
|
||||
case LinkLocal:
|
||||
@@ -90,15 +90,15 @@ func IPIsLAN(ip net.IP) bool {
|
||||
|
||||
// IPIsGlobal returns true if the given IP is a global address.
|
||||
func IPIsGlobal(ip net.IP) bool {
|
||||
return ClassifyAddress(ip) == Global
|
||||
return ClassifyIP(ip) == Global
|
||||
}
|
||||
|
||||
// IPIsLinkLocal returns true if the given IP is a link-local address.
|
||||
func IPIsLinkLocal(ip net.IP) bool {
|
||||
return ClassifyAddress(ip) == LinkLocal
|
||||
return ClassifyIP(ip) == LinkLocal
|
||||
}
|
||||
|
||||
// IPIsSiteLocal returns true if the given IP is a site-local address.
|
||||
func IPIsSiteLocal(ip net.IP) bool {
|
||||
return ClassifyAddress(ip) == SiteLocal
|
||||
return ClassifyIP(ip) == SiteLocal
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ func TestIPClassification(t *testing.T) {
|
||||
}
|
||||
|
||||
func testClassification(t *testing.T, ip net.IP, expectedClassification int8) {
|
||||
c := ClassifyAddress(ip)
|
||||
c := ClassifyIP(ip)
|
||||
if c != expectedClassification {
|
||||
t.Errorf("%s is %s, expected %s", ip, classificationString(c), classificationString(expectedClassification))
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ const (
|
||||
ACCEPT
|
||||
BLOCK
|
||||
DROP
|
||||
RerouteToNameserver
|
||||
RerouteToTunnel
|
||||
)
|
||||
|
||||
// Packer Directions
|
||||
|
||||
Reference in New Issue
Block a user