2020-10-24 17:44:14 +01:00
|
|
|
package config
|
|
|
|
|
|
|
|
import (
|
2020-11-29 22:06:38 +00:00
|
|
|
"encoding/base64"
|
2020-10-24 17:44:14 +01:00
|
|
|
"fmt"
|
2020-11-29 22:06:38 +00:00
|
|
|
"mpbl3p/crypto"
|
|
|
|
"mpbl3p/crypto/sharedkey"
|
2021-03-25 13:54:12 +00:00
|
|
|
"mpbl3p/flags"
|
2020-10-24 18:27:31 +01:00
|
|
|
"mpbl3p/proxy"
|
|
|
|
"mpbl3p/tcp"
|
|
|
|
"mpbl3p/tun"
|
2020-11-26 18:55:29 +00:00
|
|
|
"mpbl3p/udp"
|
2020-11-26 22:15:22 +00:00
|
|
|
"mpbl3p/udp/congestion"
|
|
|
|
"time"
|
2020-10-24 17:44:14 +01:00
|
|
|
)
|
|
|
|
|
2021-03-25 13:54:12 +00:00
|
|
|
func (c Configuration) Build(o *flags.Options) (*proxy.Proxy, error) {
|
2020-11-01 20:41:42 +00:00
|
|
|
p := proxy.NewProxy(0)
|
2020-11-29 22:06:38 +00:00
|
|
|
|
|
|
|
var g func() proxy.MacGenerator
|
|
|
|
var v func() proxy.MacVerifier
|
|
|
|
|
|
|
|
switch c.Host.Crypto {
|
|
|
|
case "None":
|
|
|
|
g = func() proxy.MacGenerator { return crypto.None{} }
|
|
|
|
v = func() proxy.MacVerifier { return crypto.None{} }
|
|
|
|
case "Blake2s":
|
|
|
|
key, err := base64.StdEncoding.DecodeString(c.Host.SharedKey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if _, err := sharedkey.NewBlake2s(key); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
g = func() proxy.MacGenerator {
|
|
|
|
g, _ := sharedkey.NewBlake2s(key)
|
|
|
|
return g
|
|
|
|
}
|
|
|
|
v = func() proxy.MacVerifier {
|
|
|
|
v, _ := sharedkey.NewBlake2s(key)
|
|
|
|
return v
|
|
|
|
}
|
|
|
|
}
|
2020-10-24 17:44:14 +01:00
|
|
|
|
2021-03-25 13:54:12 +00:00
|
|
|
ifName := o.InterfaceName
|
|
|
|
if ifName == "" {
|
|
|
|
ifName = "nc%d"
|
2020-11-02 17:24:15 +00:00
|
|
|
}
|
|
|
|
|
2021-03-25 13:54:12 +00:00
|
|
|
ss, err := tun.NewTun(ifName, 1500)
|
2020-10-25 15:36:34 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
p.Source = ss
|
|
|
|
p.Sink = ss
|
|
|
|
|
2020-10-24 17:44:14 +01:00
|
|
|
for _, peer := range c.Peers {
|
|
|
|
switch peer.Method {
|
|
|
|
case "TCP":
|
2021-01-23 15:59:37 +00:00
|
|
|
if err := buildTcp(p, peer, g, v); err != nil {
|
2020-10-24 17:44:14 +01:00
|
|
|
return nil, err
|
|
|
|
}
|
2020-11-26 18:55:29 +00:00
|
|
|
case "UDP":
|
2021-01-23 15:59:37 +00:00
|
|
|
if err := buildUdp(p, peer, g, v); err != nil {
|
2020-11-26 18:55:29 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
2020-10-24 17:44:14 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-01 16:50:02 +00:00
|
|
|
return p, nil
|
2020-10-24 17:44:14 +01:00
|
|
|
}
|
|
|
|
|
2021-01-23 14:36:44 +00:00
|
|
|
func buildTcp(p *proxy.Proxy, peer Peer, g func() proxy.MacGenerator, v func() proxy.MacVerifier) error {
|
2021-02-27 18:30:41 +00:00
|
|
|
var laddr func() string
|
|
|
|
if peer.LocalPort == 0 {
|
|
|
|
laddr = func() string { return fmt.Sprintf("%s:", peer.GetLocalHost()) }
|
|
|
|
} else {
|
|
|
|
laddr = func() string { return fmt.Sprintf("%s:%d", peer.GetLocalHost(), peer.LocalPort) }
|
|
|
|
}
|
|
|
|
|
2020-11-01 16:50:02 +00:00
|
|
|
if peer.RemoteHost != "" {
|
2021-02-27 18:30:41 +00:00
|
|
|
f, err := tcp.InitiateFlow(laddr, fmt.Sprintf("%s:%d", peer.RemoteHost, peer.RemotePort))
|
2020-10-24 17:44:14 +01:00
|
|
|
|
2020-11-26 18:55:29 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-01-23 14:36:44 +00:00
|
|
|
p.AddConsumer(f, g())
|
|
|
|
p.AddProducer(f, v())
|
2020-11-01 16:50:02 +00:00
|
|
|
|
2020-11-26 18:55:29 +00:00
|
|
|
return nil
|
2020-10-24 17:44:14 +01:00
|
|
|
}
|
|
|
|
|
2021-02-27 18:30:41 +00:00
|
|
|
err := tcp.NewListener(p, laddr(), v, g)
|
2020-10-24 17:44:14 +01:00
|
|
|
if err != nil {
|
2020-11-01 16:50:02 +00:00
|
|
|
return err
|
2020-10-24 17:44:14 +01:00
|
|
|
}
|
|
|
|
|
2020-11-01 16:50:02 +00:00
|
|
|
return nil
|
2020-10-24 17:44:14 +01:00
|
|
|
}
|
2020-11-26 18:55:29 +00:00
|
|
|
|
2021-01-23 14:36:44 +00:00
|
|
|
func buildUdp(p *proxy.Proxy, peer Peer, g func() proxy.MacGenerator, v func() proxy.MacVerifier) error {
|
2021-02-27 18:30:41 +00:00
|
|
|
var laddr func() string
|
|
|
|
if peer.LocalPort == 0 {
|
|
|
|
laddr = func() string { return fmt.Sprintf("%s:", peer.GetLocalHost()) }
|
|
|
|
} else {
|
|
|
|
laddr = func() string { return fmt.Sprintf("%s:%d", peer.GetLocalHost(), peer.LocalPort) }
|
|
|
|
}
|
|
|
|
|
2020-11-27 20:17:59 +00:00
|
|
|
var c func() udp.Congestion
|
2020-11-26 22:26:01 +00:00
|
|
|
switch peer.Congestion {
|
|
|
|
case "None":
|
2020-11-29 22:06:38 +00:00
|
|
|
c = func() udp.Congestion { return congestion.NewNone() }
|
2020-11-26 22:26:01 +00:00
|
|
|
default:
|
|
|
|
fallthrough
|
|
|
|
case "NewReno":
|
2020-11-29 22:06:38 +00:00
|
|
|
c = func() udp.Congestion { return congestion.NewNewReno() }
|
2020-11-26 22:26:01 +00:00
|
|
|
}
|
|
|
|
|
2020-11-26 18:55:29 +00:00
|
|
|
if peer.RemoteHost != "" {
|
|
|
|
f, err := udp.InitiateFlow(
|
2021-02-27 18:30:41 +00:00
|
|
|
laddr,
|
2020-11-26 18:55:29 +00:00
|
|
|
fmt.Sprintf("%s:%d", peer.RemoteHost, peer.RemotePort),
|
2021-01-23 14:36:44 +00:00
|
|
|
v(),
|
|
|
|
g(),
|
2020-11-27 20:17:59 +00:00
|
|
|
c(),
|
2020-11-26 22:15:22 +00:00
|
|
|
time.Duration(peer.KeepAlive)*time.Second,
|
2020-11-26 18:55:29 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-01-23 14:36:44 +00:00
|
|
|
p.AddConsumer(f, g())
|
|
|
|
p.AddProducer(f, v())
|
2020-11-26 18:55:29 +00:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-02-27 18:30:41 +00:00
|
|
|
err := udp.NewListener(p, laddr(), v, g, c)
|
2020-11-26 18:55:29 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|