Skip to content
This repository has been archived by the owner on Mar 29, 2024. It is now read-only.

Commit

Permalink
Merge pull request #5 from safing/fix/bootstrapping
Browse files Browse the repository at this point in the history
Fix bootstrapping and network integration
  • Loading branch information
dhaavi authored Aug 12, 2020
2 parents 018546e + 69ebb46 commit c169261
Show file tree
Hide file tree
Showing 11 changed files with 80 additions and 48 deletions.
1 change: 0 additions & 1 deletion api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ const (

type API interface {
Init(server, initiator bool, fromShip, toShip chan *container.Container)
GetNextID() uint32
Run()
Send(id uint32, msgType uint8, c *container.Container)
EndCall(id uint32)
Expand Down
44 changes: 24 additions & 20 deletions api/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,6 @@ func (api *APIBase) RegisterHandler(id uint8, handler ApiHandler) {
api.handlers[id] = handler
}

func (api *APIBase) GetNextID() uint32 {
for {
if api.nextID > 2147483640 {
api.nextID -= 2147483640
}
api.nextID += 2
api.activeCallsLock.Lock()
_, ok := api.activeCalls[api.nextID]
api.activeCallsLock.Unlock()
if !ok {
return api.nextID
}
}
}

func (api *APIBase) Run() {
for {
c := <-api.fromShip
Expand Down Expand Up @@ -147,20 +132,39 @@ func (api *APIBase) Call(handlerID uint8, c *container.Container) *Call {
newCall := &Call{
Api: api,
Initiator: true,
ID: api.GetNextID(),
Msgs: make(chan *ApiMsg, 0),
ended: abool.NewBool(false),
}

api.activeCallsLock.Lock()
api.activeCalls[newCall.ID] = newCall
api.activeCallsLock.Unlock()
api.RegisterCall(newCall)

c.Prepend(varint.Pack8(handlerID))
newCall.send(API_CALL, c)
return newCall
}

func (api *APIBase) RegisterCall(call *Call) {
api.activeCallsLock.Lock()
defer api.activeCallsLock.Unlock()

for {
// wrap around
if api.nextID > 2147483640 {
api.nextID -= 2147483640
}
// increase call counter
api.nextID += 2

// check if ID is already registered
_, ok := api.activeCalls[api.nextID]
if !ok {
// use if free
call.ID = api.nextID
api.activeCalls[call.ID] = call
return
}
}
}

func (api *APIBase) Send(id uint32, msgType uint8, c *container.Container) {
if !api.abandoned.IsSet() {
c.Prepend(varint.Pack8(msgType))
Expand Down
1 change: 1 addition & 0 deletions api/call.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ func (call *Call) send(msgType uint8, c *container.Container) {
}

func (call *Call) End() {
call.send(API_END, container.NewContainer(nil))
call.ended.Set()
call.Api.EndCall(call.ID)
}
Expand Down
10 changes: 7 additions & 3 deletions captain/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,23 @@ func init() {
flag.StringVar(&bootstrapFileFlag, "bootstrap-file", "", "bootstrap file containing bootstrap hubs - will be initialized if running a public hub and it doesn't exist")
}

// processBootstrapFileFlag cehcks the bootstrap-hub argument if it is valid.
// prepBootstrapHubFlag cehcks the bootstrap-hub argument if it is valid.
func prepBootstrapHubFlag() error {
if bootstrapHubFlag != "" {
return processBootstrapHub(bootstrapHubFlag, false)
}
return nil
}

// processBootstrapFileFlag processes the bootstrap-file argument.
// processBootstrapHubFlag processes the bootstrap-hub argument.
func processBootstrapHubFlag() error {
if bootstrapHubFlag != "" {
return processBootstrapHub(bootstrapHubFlag, true)
}
return nil
}

// processBootstrapFileFlag processes the bootstrap-file argument.
// processBootstrapHub processes the bootstrap-hub argument.
func processBootstrapHub(bootstrapTransport string, save bool) error {
// parse argument
t, err := hub.ParseTransport(bootstrapTransport)
Expand Down Expand Up @@ -132,6 +132,10 @@ func processBootstrapFileFlag() error {

// bootstrapWithUpdates loads bootstrap hubs from the updates server and imports them.
func bootstrapWithUpdates() error {
if bootstrapFileFlag != "" {
return errors.New("using the bootstrap-file argument disables bootstrapping via the update system")
}

file, err := updates.GetFile("spn/bootstrap.dsd")
if err != nil {
return fmt.Errorf("failed to get updates file: %w", err)
Expand Down
14 changes: 14 additions & 0 deletions captain/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/safing/spn/conf"
"github.com/safing/spn/docks"
"github.com/safing/spn/hub"
"github.com/safing/spn/navigator"
)

func initDockHooks() {
Expand Down Expand Up @@ -87,6 +88,17 @@ func handleDiscontinuedConnection(
connectedHub *hub.Hub,
c *container.Container,
) error {
// do nothing if identity is unknown - there is no higher level logic initiated by us
if connectedHub == nil {
return nil
}

// shutdown any active API
port := navigator.GetPublicPort(connectedHub.ID)
if port != nil && port.ActiveAPI != nil {
port.ActiveAPI.Shutdown()
}

// do nothing if we're not a public hub
if !conf.PublicHub() {
return nil
Expand All @@ -100,6 +112,8 @@ func handleDiscontinuedConnection(
// update status
updateConnectionStatus()

// TODO: prepone restart if we loose all connections (ie. all connected hubs are restarting and no client are connected)

return nil
}

Expand Down
10 changes: 0 additions & 10 deletions captain/updates.go

This file was deleted.

10 changes: 7 additions & 3 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,19 @@ import (
)

func main() {
// configure
info.Set("SPN Hub", "0.2.0", "AGPLv3", true)
info.Set("SPN Client Simulator", "0.0.0", "AGPLv3", false)

// configure SPN
conf.EnablePublicHub(false)
conf.EnableClient(true)
config.SetDefaultConfigOption(captain.CfgOptionEnableSPNKey, true)

go clientSim()
// adapt portmaster updates module
updates.MandatoryUpdates = []string{}
updates.UserAgent = "Hub"

// start
go clientSim()
os.Exit(run.Run())
}

Expand Down
4 changes: 4 additions & 0 deletions docks/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ func (portAPI *API) relay(call *api.Call, conveyor *SimpleConveyorLine) {
for {
select {
case msg := <-call.Msgs:
if msg == nil { // call ended
close(conveyor.toShore)
return
}
switch msg.MsgType {
case api.API_DATA:
conveyor.toShore <- msg.Container
Expand Down
8 changes: 7 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,21 @@ import (

// include packages here
_ "github.com/safing/portmaster/core/base"
"github.com/safing/portmaster/updates"
)

func main() {
// configure
info.Set("SPN Hub", "0.2.1", "AGPLv3", true)

// configure SPN
conf.EnablePublicHub(true)
conf.EnableClient(false)
config.SetDefaultConfigOption(captain.CfgOptionEnableSPNKey, true)

// adapt portmaster updates module
updates.MandatoryUpdates = []string{}
updates.UserAgent = "Hub"

// start
os.Exit(run.Run())
}
2 changes: 1 addition & 1 deletion sluice/navigator.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func buildTunnel(r *Request) (*api.Call, error) {
if !ports[0].HasActiveRoute() {
return nil, errors.New("first port in route has no active client")
}
log.Tracef("spn/sluice: found route with %d (additional) hops and with exit %s", len(ports), ports[len(ports)-1].Hub)
log.Tracef("spn/sluice: found route with %d (additional) hops and with exit %s", len(ports)-1, ports[len(ports)-1].Hub)

// get access code
accessCode, err := access.Get()
Expand Down
24 changes: 15 additions & 9 deletions sluice/sluice-stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"net"
"time"

"github.com/safing/portmaster/network/netutils"

"github.com/tevino/abool"

"github.com/safing/portbase/container"
Expand Down Expand Up @@ -69,20 +71,24 @@ func (s *StreamSluice) handler(ctx context.Context) error {
func (s *StreamSluice) handleConnection(ctx context.Context, conn net.Conn) error {
defer conn.Close()

// get addresses
localAddr, ok := conn.LocalAddr().(*net.TCPAddr)
if !ok {
return fmt.Errorf("failed to get local address, unexpected type: %T", conn.LocalAddr())
}
// get remote address
remoteAddr, ok := conn.RemoteAddr().(*net.TCPAddr)
if !ok {
return fmt.Errorf("failed to get remote address, unexpected type: %T", conn.RemoteAddr())
}

// check if local
if !remoteAddr.IP.Equal(localAddr.IP) {
log.Debugf("spn/sluice: received non-local request from %s", remoteAddr)
return nil
// get local address
localAddr, ok := conn.LocalAddr().(*net.TCPAddr)
if !ok {
return fmt.Errorf("failed to get local address, unexpected type: %T", conn.LocalAddr())
}

if !netutils.IPIsLocalhost(localAddr.IP) {
// If request is not from a localhost address, check it it's really local.
if !remoteAddr.IP.Equal(localAddr.IP) {
log.Debugf("spn/sluice: received non-local request from %s", remoteAddr)
return nil
}
}

// get request
Expand Down

0 comments on commit c169261

Please sign in to comment.