From 5dde5e766c0178a80416e3ec8f3ffc55a2691ed2 Mon Sep 17 00:00:00 2001 From: maride Date: Fri, 7 Sep 2018 14:04:58 +0200 Subject: Cleanup, react to signals (\^C), tidy up and sort code --- src/access.go | 90 ++++++++++++++++++++++------------------------------------- 1 file changed, 33 insertions(+), 57 deletions(-) (limited to 'src/access.go') diff --git a/src/access.go b/src/access.go index 4ae96ed..6f0d848 100644 --- a/src/access.go +++ b/src/access.go @@ -16,13 +16,10 @@ import ( ) const( - vpnHostNetworkName = "vpnhostnet" vpnContainerName = "circus-vpn" ) var vpnContainerID string -var vpnNetworkID string -var vpnHostNetworkID string var remoteAddress* string var remotePort* int @@ -32,24 +29,35 @@ func registerAccessFlags() { } func startVPN() (err error) { + // First: try to stop an existing container with that name, to avoid collision + // This container may exist if we didn't properly clean up on the last run, e.g. if the companion crashed. + stopVPN() + // stopVPN() as first command in startVPN()... This looks strange, but is perfectly fine ;) + // Set up our context and Docker CLI connection setupContext() setupDockerCLI() - // Set up network - err = setupNetwork() - if(err != nil) { - return err + // Set up VPN host network + if vpnHostNetworkID == "" { + id, err := setupNetwork(vpnHostNetworkName, false) + if (err != nil) { + return err + } + vpnHostNetworkID = id } - err = setupVPNHostNetwork() - - if err != nil { - return err + // Set up container network + if containerNetworkID == "" { + id, err := setupNetwork(containerNetworkName, true) + if (err != nil) { + return err + } + containerNetworkID = id } // Get subnet of challenge container network, to hand it over to our VPN container for routes - inspectResp, err := dockerCli.NetworkInspect(dockerCtx, vpnNetworkID, types.NetworkInspectOptions{}) + inspectResp, err := dockerCli.NetworkInspect(dockerCtx, containerNetworkID, types.NetworkInspectOptions{}) if err != nil { return err } @@ -95,7 +103,7 @@ func startVPN() (err error) { } // Attach container network to VPN container - err = dockerCli.NetworkConnect(dockerCtx, vpnNetworkID, resp.ID, &network.EndpointSettings{}) + err = dockerCli.NetworkConnect(dockerCtx, containerNetworkID, resp.ID, &network.EndpointSettings{}) if err != nil { return err } @@ -110,7 +118,7 @@ func startVPN() (err error) { // However, getCertificate() requires that port 9999 of the VPN container hosts the configuration files for our client. // That means we need to attach our own container - thanks to --privileged mode - into the VPN container network. // We get the ID of our container from the "hostname" environment variable. That's a bit dirty, but works for the moment. TODO: solve this better. - err = dockerCli.NetworkConnect(dockerCtx, vpnNetworkID, os.Getenv("HOSTNAME"), &network.EndpointSettings{}) + err = dockerCli.NetworkConnect(dockerCtx, vpnHostNetworkID, os.Getenv("HOSTNAME"), &network.EndpointSettings{}) if err != nil { return err } @@ -130,44 +138,6 @@ func stopVPN() { vpnContainerID = "" } -func setupNetwork() (error) { - setupContext() - setupDockerCLI() - - if vpnNetworkID == "" { - response, err := dockerCli.NetworkCreate(dockerCtx, VPNNetworkName, types.NetworkCreate{ - Internal: true, - }) - - if err != nil { - return err - } - - vpnNetworkID = response.ID - } - - return nil -} - -func setupVPNHostNetwork() (error) { - setupContext() - setupDockerCLI() - - if vpnHostNetworkID == "" { - response, err := dockerCli.NetworkCreate(dockerCtx, vpnHostNetworkName, types.NetworkCreate{ - Internal: false, - }) - - if err != nil { - return err - } - - vpnHostNetworkID = response.ID - } - - return nil -} - func getCertificate() (string, error) { if vpnContainerID == "" { return "", errors.New("VPN container not up") @@ -182,16 +152,22 @@ func getCertificate() (string, error) { // get certificate var certResponse *http.Response + // retry for 10 seconds to dial to the VPN container for i := 0; i < 10; i++ { - certResponse, err = http.Get(fmt.Sprintf("http://%s:9999/", inspectJSON.NetworkSettings.Networks[VPNNetworkName].IPAddress)) - - if err == nil { - break + // Check if the VPN container is already part of our challenge container network + if inspectJSON.NetworkSettings.Networks[vpnHostNetworkName] != nil { + // it is - get the IP address and dial to it + certResponse, err = http.Get(fmt.Sprintf("http://%s:9999/", inspectJSON.NetworkSettings.Networks[vpnHostNetworkName].IPAddress)) + + if err == nil { + break + } } + time.Sleep(time.Second) } - if err != nil { + if err != nil || certResponse == nil { return "", err } -- cgit 1.4.1