-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
103 lines (85 loc) · 2.21 KB
/
main.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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package main
import (
"fmt"
"net"
"os"
"time"
"github.com/aspcartman/roskompozor/rkn"
"github.com/aspcartman/roskompozor/route"
"github.com/aspcartman/roskompozor/sets"
"github.com/aspcartman/roskompozor/sniff"
"github.com/sirupsen/logrus"
)
func main() {
if len(os.Args) != 3 {
fmt.Println("Usage: roskompozor <main_iface> <vpn_iface>")
os.Exit(-1)
}
router{
Main: os.Args[1],
VPN: os.Args[2],
Source: rkn.ZapretInfo,
}.routeLoop()
}
type router struct {
Main string
VPN string
Source rkn.Source
bannedRefresh time.Time
banned sets.IPs
routedRefresh time.Time
routed sets.IPs
}
func (r router) routeLoop() {
r.refreshBanned()
r.refreshRouted()
logrus.WithFields(logrus.Fields{"main": r.Main, "vpn": r.VPN}).Info("listening and routing")
for {
if err := sniff.Sniff(r.Main, func(ip net.IP) {
switch {
case r.banned.Contains(ip) && !r.routed.Contains(ip):
r.route(ip)
case time.Since(r.routedRefresh) > 10*time.Second:
r.refreshRouted()
case time.Since(r.bannedRefresh) > 10*time.Minute:
r.refreshBanned()
}
}, func(host string) {
}); err != nil {
logrus.WithError(err).Error("failed sniffing network traffic")
}
time.Sleep(2 * time.Second)
}
}
func (r *router) route(ip net.IP) {
if err := route.Add(ip, r.VPN); err != nil {
logrus.WithError(err).Error("failed adding route")
return
}
r.routed.AddIP(ip)
logrus.WithField("ip", ip).WithField("dest", r.VPN).Info("routed")
}
func (r *router) refreshBanned() {
logrus.Info("refreshing banned")
retry:
set, err := r.Source()
if err != nil {
logrus.WithError(err).Error("failed fetching banned ips")
time.Sleep(2 * time.Second)
goto retry
}
r.banned, r.bannedRefresh = set, time.Now()
logrus.WithFields(logrus.Fields{"ips": len(set.IPs), "networks": len(set.Nets)}).Info("refreshed banned ips")
}
func (r *router) refreshRouted() {
logrus.Info("refreshing routed")
retry:
set, err := route.Routed()
if err != nil {
logrus.WithError(err).Error("failed fetching routed ips")
time.Sleep(2 * time.Second)
goto retry
}
r.routed, r.routedRefresh = set, time.Now()
logrus.WithFields(logrus.Fields{"ips": len(set.IPs), "networks": len(set.Nets)}).Info("refreshed routed ips")
}