|
@@ -38,6 +38,7 @@ import (
|
|
|
"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/buildinfo"
|
|
"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/buildinfo"
|
|
|
"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/errors"
|
|
"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/errors"
|
|
|
"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/osl"
|
|
"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/osl"
|
|
|
|
|
+ "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/packetman"
|
|
|
"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/tactics"
|
|
"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/tactics"
|
|
|
"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/tun"
|
|
"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/tun"
|
|
|
"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/server/psinet"
|
|
"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/server/psinet"
|
|
@@ -46,25 +47,32 @@ import (
|
|
|
// RunServices initializes support functions including logging and GeoIP services;
|
|
// RunServices initializes support functions including logging and GeoIP services;
|
|
|
// and then starts the server components and runs them until os.Interrupt or
|
|
// and then starts the server components and runs them until os.Interrupt or
|
|
|
// os.Kill signals are received. The config determines which components are run.
|
|
// os.Kill signals are received. The config determines which components are run.
|
|
|
-func RunServices(configJSON []byte) error {
|
|
|
|
|
|
|
+func RunServices(configJSON []byte) (retErr error) {
|
|
|
|
|
+
|
|
|
|
|
+ loggingInitialized := false
|
|
|
|
|
+
|
|
|
|
|
+ defer func() {
|
|
|
|
|
+ if retErr != nil && loggingInitialized {
|
|
|
|
|
+ log.WithTraceFields(LogFields{"error": retErr}).Error("RunServices failed")
|
|
|
|
|
+ }
|
|
|
|
|
+ }()
|
|
|
|
|
|
|
|
rand.Seed(int64(time.Now().Nanosecond()))
|
|
rand.Seed(int64(time.Now().Nanosecond()))
|
|
|
|
|
|
|
|
config, err := LoadConfig(configJSON)
|
|
config, err := LoadConfig(configJSON)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.WithTraceFields(LogFields{"error": err}).Error("load config failed")
|
|
|
|
|
return errors.Trace(err)
|
|
return errors.Trace(err)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
err = InitLogging(config)
|
|
err = InitLogging(config)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.WithTraceFields(LogFields{"error": err}).Error("init logging failed")
|
|
|
|
|
return errors.Trace(err)
|
|
return errors.Trace(err)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ loggingInitialized = true
|
|
|
|
|
+
|
|
|
supportServices, err := NewSupportServices(config)
|
|
supportServices, err := NewSupportServices(config)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.WithTraceFields(LogFields{"error": err}).Error("init support services failed")
|
|
|
|
|
return errors.Trace(err)
|
|
return errors.Trace(err)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -78,7 +86,6 @@ func RunServices(configJSON []byte) error {
|
|
|
|
|
|
|
|
tunnelServer, err := NewTunnelServer(supportServices, shutdownBroadcast)
|
|
tunnelServer, err := NewTunnelServer(supportServices, shutdownBroadcast)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.WithTraceFields(LogFields{"error": err}).Error("init tunnel server failed")
|
|
|
|
|
return errors.Trace(err)
|
|
return errors.Trace(err)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -97,13 +104,27 @@ func RunServices(configJSON []byte) error {
|
|
|
AllowBogons: config.AllowBogons,
|
|
AllowBogons: config.AllowBogons,
|
|
|
})
|
|
})
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.WithTraceFields(LogFields{"error": err}).Error("init packet tunnel failed")
|
|
|
|
|
return errors.Trace(err)
|
|
return errors.Trace(err)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
supportServices.PacketTunnelServer = packetTunnelServer
|
|
supportServices.PacketTunnelServer = packetTunnelServer
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if config.RunPacketManipulator {
|
|
|
|
|
+
|
|
|
|
|
+ packetManipulatorConfig, err := makePacketManipulatorConfig(supportServices)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return errors.Trace(err)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ packetManipulator, err := packetman.NewManipulator(packetManipulatorConfig)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return errors.Trace(err)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ supportServices.PacketManipulator = packetManipulator
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// After this point, errors should be delivered to the errors channel and
|
|
// After this point, errors should be delivered to the errors channel and
|
|
|
// orderly shutdown should flow through to the end of the function to ensure
|
|
// orderly shutdown should flow through to the end of the function to ensure
|
|
|
// all workers are synchronously stopped.
|
|
// all workers are synchronously stopped.
|
|
@@ -118,6 +139,23 @@ func RunServices(configJSON []byte) error {
|
|
|
}()
|
|
}()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if config.RunPacketManipulator {
|
|
|
|
|
+ err := supportServices.PacketManipulator.Start()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ select {
|
|
|
|
|
+ case errorChannel <- err:
|
|
|
|
|
+ default:
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ waitGroup.Add(1)
|
|
|
|
|
+ go func() {
|
|
|
|
|
+ defer waitGroup.Done()
|
|
|
|
|
+ <-shutdownBroadcast
|
|
|
|
|
+ supportServices.PacketManipulator.Stop()
|
|
|
|
|
+ }()
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if config.RunLoadMonitor() {
|
|
if config.RunLoadMonitor() {
|
|
|
waitGroup.Add(1)
|
|
waitGroup.Add(1)
|
|
|
go func() {
|
|
go func() {
|
|
@@ -256,7 +294,6 @@ loop:
|
|
|
break loop
|
|
break loop
|
|
|
|
|
|
|
|
case err = <-errorChannel:
|
|
case err = <-errorChannel:
|
|
|
- log.WithTraceFields(LogFields{"error": err}).Error("service failed")
|
|
|
|
|
break loop
|
|
break loop
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -397,6 +434,7 @@ type SupportServices struct {
|
|
|
PacketTunnelServer *tun.Server
|
|
PacketTunnelServer *tun.Server
|
|
|
TacticsServer *tactics.Server
|
|
TacticsServer *tactics.Server
|
|
|
Blocklist *Blocklist
|
|
Blocklist *Blocklist
|
|
|
|
|
+ PacketManipulator *packetman.Manipulator
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// NewSupportServices initializes a new SupportServices.
|
|
// NewSupportServices initializes a new SupportServices.
|
|
@@ -472,12 +510,22 @@ func (support *SupportServices) Reload() {
|
|
|
// reload; new tactics will be obtained on the next client handshake or
|
|
// reload; new tactics will be obtained on the next client handshake or
|
|
|
// tactics request.
|
|
// tactics request.
|
|
|
|
|
|
|
|
|
|
+ reloadSpecs := func() {
|
|
|
|
|
+ err := reloadPacketManipulationSpecs(support)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ log.WithTraceFields(
|
|
|
|
|
+ LogFields{"error": errors.Trace(err)}).Warning(
|
|
|
|
|
+ "failed to reload packet manipulation specs")
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// Take these actions only after the corresponding Reloader has reloaded.
|
|
// Take these actions only after the corresponding Reloader has reloaded.
|
|
|
// In both the traffic rules and OSL cases, there is some impact from state
|
|
// In both the traffic rules and OSL cases, there is some impact from state
|
|
|
// reset, so the reset should be avoided where possible.
|
|
// reset, so the reset should be avoided where possible.
|
|
|
reloadPostActions := map[common.Reloader]func(){
|
|
reloadPostActions := map[common.Reloader]func(){
|
|
|
support.TrafficRulesSet: func() { support.TunnelServer.ResetAllClientTrafficRules() },
|
|
support.TrafficRulesSet: func() { support.TunnelServer.ResetAllClientTrafficRules() },
|
|
|
support.OSLConfig: func() { support.TunnelServer.ResetAllClientOSLConfigs() },
|
|
support.OSLConfig: func() { support.TunnelServer.ResetAllClientOSLConfigs() },
|
|
|
|
|
+ support.TacticsServer: reloadSpecs,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
for _, reloader := range reloaders {
|
|
for _, reloader := range reloaders {
|