mirror of
https://github.com/nadoo/glider.git
synced 2025-02-23 01:15:41 +08:00
dpcpd: handle errors
This commit is contained in:
parent
a956e5811f
commit
02220387e9
17
README.md
17
README.md
@ -36,6 +36,8 @@ we can set up local listeners as proxy servers, and forward requests to internet
|
||||
- Serve http and socks5 on the same port
|
||||
- Periodical availability checking for forwarders
|
||||
- Send requests from specific local ip/interface
|
||||
- Services:
|
||||
- dhcpd: a simple dhcp server
|
||||
|
||||
## Protocols
|
||||
<details>
|
||||
@ -91,7 +93,7 @@ glider -h
|
||||
<summary>click to see details</summary>
|
||||
|
||||
```bash
|
||||
glider 0.10.2 usage:
|
||||
./glider 0.11.0 usage:
|
||||
-checkdisabledonly
|
||||
check disabled fowarders only
|
||||
-checkinterval int
|
||||
@ -134,6 +136,8 @@ glider 0.10.2 usage:
|
||||
rule file path
|
||||
-rules-dir string
|
||||
rule file folder
|
||||
-service value
|
||||
enable services
|
||||
-strategy string
|
||||
forward strategy, default: rr (default "rr")
|
||||
-verbose
|
||||
@ -357,7 +361,14 @@ glider -config CONFIGPATH -listen :8080 -verbose
|
||||
|
||||
</details>
|
||||
|
||||
## Service
|
||||
## Builtin Service
|
||||
|
||||
scheme: service=SERVICE_NAME[,SERVICE_CONFIG]
|
||||
- dhcpd(from v0.11.0):
|
||||
- service=dhcpd,INTERFACE,START_IP,END_IP
|
||||
- e.g., service=dhcpd,en0,192.168.254.100,192.168.254.199
|
||||
|
||||
## Linux Service
|
||||
|
||||
- systemd: [https://github.com/nadoo/glider/blob/master/systemd/](https://github.com/nadoo/glider/blob/master/systemd/)
|
||||
|
||||
@ -366,4 +377,4 @@ glider -config CONFIGPATH -listen :8080 -verbose
|
||||
- [ipset](https://github.com/nadoo/ipset): netlink ipset package for Go.
|
||||
- [conflag](https://github.com/nadoo/conflag): a drop-in replacement for Go's standard flag package with config file support.
|
||||
- [ArchLinux](https://www.archlinux.org/packages/community/x86_64/glider): a great linux distribution with glider pre-built package.
|
||||
- [urlencode](https://www.w3schools.com/tags/ref_urlencode.asp): you should encode special characters in scheme url. e.g: `@`->`%40`
|
||||
- [urlencode](https://www.w3schools.com/tags/ref_urlencode.asp): you should encode special characters in scheme url. e.g., `@`->`%40`
|
||||
|
10
go.mod
10
go.mod
@ -9,11 +9,11 @@ require (
|
||||
github.com/nadoo/go-shadowsocks2 v0.1.2
|
||||
github.com/nadoo/ipset v0.3.0
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||
github.com/xtaci/kcp-go/v5 v5.5.15
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
|
||||
golang.org/x/net v0.0.0-20200927032502-5d4f70055728 // indirect
|
||||
golang.org/x/sys v0.0.0-20200926100807-9d91bd62050c // indirect
|
||||
golang.org/x/tools v0.0.0-20200928112810-42b62fc93869 // indirect
|
||||
github.com/xtaci/kcp-go/v5 v5.5.17
|
||||
golang.org/x/crypto v0.0.0-20200930160638-afb6bcd081ae
|
||||
golang.org/x/net v0.0.0-20200930145003-4acb6c075d10 // indirect
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f // indirect
|
||||
golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
|
||||
)
|
||||
|
||||
|
20
go.sum
20
go.sum
@ -97,8 +97,8 @@ github.com/xtaci/kcp-go v5.4.11+incompatible h1:tJbtarpmOoOD74cZ41uvvF5Hyt1nvctH
|
||||
github.com/xtaci/kcp-go v5.4.11+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||
github.com/xtaci/kcp-go/v5 v5.5.12 h1:iALGyvti/oBbl1TbVoUpHEUHCorDEb3tEKl1CPY3KXM=
|
||||
github.com/xtaci/kcp-go/v5 v5.5.12/go.mod h1:H0T/EJ+lPNytnFYsKLH0JHUtiwZjG3KXlTM6c+Q4YUo=
|
||||
github.com/xtaci/kcp-go/v5 v5.5.15 h1:I/T1Mf1xWYJd7jjHlCcP+FsBxuPJJ3VPP/vfTgUX8lk=
|
||||
github.com/xtaci/kcp-go/v5 v5.5.15/go.mod h1:pVx3jb4LT5edTmPayc77tIU9nRsjGck8wep5ZV/RBO0=
|
||||
github.com/xtaci/kcp-go/v5 v5.5.17 h1:bkdaqtER0PMlP05BBHfu6W+71kt/NwbAk93KH7F78Ck=
|
||||
github.com/xtaci/kcp-go/v5 v5.5.17/go.mod h1:pVx3jb4LT5edTmPayc77tIU9nRsjGck8wep5ZV/RBO0=
|
||||
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM=
|
||||
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
@ -118,8 +118,8 @@ golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de h1:ikNHVSjEfnvz6sxdSPCaPt572qowuyMDMJLLm3Db3ig=
|
||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200930160638-afb6bcd081ae h1:duLSQW+DZ5MsXKX7kc4rXlq6/mmxz4G6ewJuBPlhRe0=
|
||||
golang.org/x/crypto v0.0.0-20200930160638-afb6bcd081ae/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
||||
@ -141,8 +141,8 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgN
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200927032502-5d4f70055728 h1:5wtQIAulKU5AbLQOkjxl32UufnIOqgBX72pS0AV14H0=
|
||||
golang.org/x/net v0.0.0-20200927032502-5d4f70055728/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200930145003-4acb6c075d10 h1:YfxMZzv3PjGonQYNUaeU2+DhAdqOxerQ30JFB6WgAXo=
|
||||
golang.org/x/net v0.0.0-20200930145003-4acb6c075d10/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -165,16 +165,16 @@ golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200808120158-1030fc2bf1d9 h1:yi1hN8dcqI9l8klZfy4B8mJvFmmAxJEePIQQFNSd7Cs=
|
||||
golang.org/x/sys v0.0.0-20200808120158-1030fc2bf1d9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200926100807-9d91bd62050c h1:38q6VNPWR010vN82/SB121GujZNIfAUb4YttE2rhGuc=
|
||||
golang.org/x/sys v0.0.0-20200926100807-9d91bd62050c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200425043458-8463f397d07c h1:iHhCR0b26amDCiiO+kBguKZom9aMF+NrFxh9zeKR/XU=
|
||||
golang.org/x/tools v0.0.0-20200425043458-8463f397d07c/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200808161706-5bf02b21f123/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200928112810-42b62fc93869 h1:6Zj8sAhgEtZaHYz4O/Grp2Gyh0FLb8a7sLJTanOG5QQ=
|
||||
golang.org/x/tools v0.0.0-20200928112810-42b62fc93869/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c h1:9BSeO6440XJVa2mxIcRAndAol4g4g2KflCVGcHx9Yu8=
|
||||
golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
|
@ -2,6 +2,7 @@ package dhcpd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
@ -28,25 +29,24 @@ func (*dpcpd) Run(args ...string) {
|
||||
return
|
||||
}
|
||||
|
||||
iface, ipStart, ipEnd := args[0], args[1], args[2]
|
||||
iface := args[0]
|
||||
ip, mask, err := intfaceIP4(iface)
|
||||
if err != nil {
|
||||
log.F("[dhcpd] get ip of interface '%s' error: %s", iface, err)
|
||||
return
|
||||
}
|
||||
|
||||
if detectServer(iface) {
|
||||
if findExistServer(iface) {
|
||||
log.F("[dhcpd] found existing dhcp server on interface %s, service exiting", iface)
|
||||
return
|
||||
}
|
||||
|
||||
pool, err := NewPool(leaseTime, net.ParseIP(ipStart), net.ParseIP(ipEnd))
|
||||
pool, err := NewPool(leaseTime, net.ParseIP(args[1]), net.ParseIP(args[2]))
|
||||
if err != nil {
|
||||
log.F("[dhcpd] error in pool init: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
ip, mask := ifaceIPMask4(iface)
|
||||
if ip == nil || mask == nil {
|
||||
log.F("[dhcpd] can not get ip and mask of interface: %s", iface)
|
||||
return
|
||||
}
|
||||
|
||||
laddr := net.UDPAddr{IP: net.IPv4(0, 0, 0, 0), Port: 67}
|
||||
server, err := server4.NewServer(iface, &laddr, handleDHCP(ip, mask, pool))
|
||||
if err != nil {
|
||||
@ -54,7 +54,7 @@ func (*dpcpd) Run(args ...string) {
|
||||
return
|
||||
}
|
||||
|
||||
log.F("[dhcpd] listening on interface %s(%s/%d.%d.%d.%d)",
|
||||
log.F("[dhcpd] Listening on interface %s(%s/%d.%d.%d.%d)",
|
||||
iface, ip, mask[0], mask[1], mask[2], mask[3])
|
||||
|
||||
server.Serve()
|
||||
@ -62,7 +62,6 @@ func (*dpcpd) Run(args ...string) {
|
||||
|
||||
func handleDHCP(serverIP net.IP, mask net.IPMask, pool *Pool) server4.Handler {
|
||||
return func(conn net.PacketConn, peer net.Addr, m *dhcpv4.DHCPv4) {
|
||||
// log.F("[dpcpd] received request from client %v", m.ClientHWAddr)
|
||||
|
||||
var replyType dhcpv4.MessageType
|
||||
switch mt := m.MessageType(); mt {
|
||||
@ -84,15 +83,14 @@ func handleDHCP(serverIP net.IP, mask net.IPMask, pool *Pool) server4.Handler {
|
||||
reply, err := dhcpv4.NewReplyFromRequest(m,
|
||||
dhcpv4.WithMessageType(replyType),
|
||||
dhcpv4.WithServerIP(serverIP),
|
||||
dhcpv4.WithRouter(serverIP),
|
||||
dhcpv4.WithNetmask(mask),
|
||||
dhcpv4.WithYourIP(replyIp),
|
||||
dhcpv4.WithRouter(serverIP),
|
||||
dhcpv4.WithDNS(serverIP),
|
||||
// RFC 2131, Section 4.3.1. Server Identifier: MUST
|
||||
dhcpv4.WithOption(dhcpv4.OptServerIdentifier(serverIP)),
|
||||
// RFC 2131, Section 4.3.1. IP lease time: MUST
|
||||
dhcpv4.WithOption(dhcpv4.OptIPAddressLeaseTime(leaseTime)),
|
||||
dhcpv4.WithRouter(serverIP),
|
||||
dhcpv4.WithDNS(serverIP),
|
||||
)
|
||||
|
||||
if val := m.Options.Get(dhcpv4.OptionClientIdentifier); len(val) > 0 {
|
||||
@ -108,7 +106,7 @@ func handleDHCP(serverIP net.IP, mask net.IPMask, pool *Pool) server4.Handler {
|
||||
}
|
||||
}
|
||||
|
||||
func detectServer(iface string) (exists bool) {
|
||||
func findExistServer(iface string) (exists bool) {
|
||||
client, err := nclient4.New(iface)
|
||||
if err != nil {
|
||||
log.F("[dhcpd] failed in dhcp client creation: %s", err)
|
||||
@ -125,24 +123,27 @@ func detectServer(iface string) (exists bool) {
|
||||
return true
|
||||
}
|
||||
|
||||
func ifaceIPMask4(iface string) (net.IP, net.IPMask) {
|
||||
func intfaceIP4(iface string) (net.IP, net.IPMask, error) {
|
||||
intf, err := net.InterfaceByName(iface)
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
addrs, err := intf.Addrs()
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
for _, addr := range addrs {
|
||||
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
||||
if ipnet, ok := addr.(*net.IPNet); ok {
|
||||
if ipnet.IP.IsLoopback() {
|
||||
return nil, nil, errors.New("can't use loopback interface")
|
||||
}
|
||||
if ip4 := ipnet.IP.To4(); ip4 != nil {
|
||||
return ip4, ipnet.Mask
|
||||
return ip4, ipnet.Mask, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
return nil, nil, errors.New("no ip/mask defined on this interface")
|
||||
}
|
||||
|
@ -14,7 +14,15 @@ type Pool struct {
|
||||
|
||||
// NewPool returns a new dhcp ip pool.
|
||||
func NewPool(lease time.Duration, start, end net.IP) (*Pool, error) {
|
||||
if start == nil || end == nil {
|
||||
return nil, errors.New("start ip or end ip is wrong/nil, please check your config")
|
||||
}
|
||||
|
||||
s, e := ip2num(start.To4()), ip2num(end.To4())
|
||||
if e < s {
|
||||
return nil, errors.New("start ip larger than end ip")
|
||||
}
|
||||
|
||||
items := make([]*item, 0, e-s+1)
|
||||
for n := s; n <= e; n++ {
|
||||
items = append(items, &item{lease: lease, ip: num2ip(n)})
|
||||
|
Loading…
Reference in New Issue
Block a user