func (s *Segment) Cleanup() { if s.Proxy != nil { s.Proxy.StopProxy("segment") s.Proxy = nil } if s.ChildId != "" { if s.ChildHost == "" { deleteSegment(s.ChildId) } else { c, err := client.NewClient(s.ChildHost, opts.config) if err != nil { glog.Errorf("Failed to connect to child host at %s: %v", s.ChildHost, err) } else { c.DeleteSegment(s.ChildId) } } } if len(s.DockerIds) != 0 { args := []string{"rm", "-f"} args = append(args, s.DockerIds...) out, err := exec.Command("docker", args...).CombinedOutput() if err != nil { glog.Errorf("Error deleting docker container %v: %s", err, out) } } if s.Head.Ns.IsOpen() { s.Head.Ns.Close() } if s.Tail.Ns.IsOpen() { s.Tail.Ns.Close() } }
func deleteTunnel(host string) error { c, err := client.NewClient(host, opts.config) if err != nil { return err } defer c.Close() dst, _ := c.DestroyTunnel(opts.external) if dst != nil { destroyTunnel(dst) } return nil }
func Main() { args := parseFlags() if len(args) == 0 { usage("") return } command, args := args[0], args[1:] if command == "help" { if len(args) != 0 { usage(args[0]) } else { usage("") } return } c, err := client.NewClient(opts.host, opts.config) if err != nil { log.Fatalf("Failed to create client: %v", err) } defer c.Close() switch command { case "ping": ping(args, c) case "create": segmentCreate(args, c) case "delete": segmentDelete(args, c) case "tunnel-create": tunnelCreate(args, c) case "tunnel-delete": tunnelDelete(args, c) default: log.Printf("Unknown command: %v", command) usage("") } }
func echo(host string, value []byte) ([]byte, error) { glog.Infof("Echo called with: %v %v", host, value) if host == "" { return value, nil } else { host, err := utils.ValidateAddr(host) if err != nil { return nil, err } c, err := client.NewClient(host, opts.config) if err != nil { return nil, err } response, err := c.Echo(value, "") if err != nil { return nil, err } if !bytes.Equal(value, response) { return response, fmt.Errorf("Incorrect response from echo") } glog.Infof("Echo response is: %v", response) return response, nil } }
func executeTunnel(command *client.SegmentCommand, seg *Segment, udp bool) error { _, dst, err := createTunnel(command.Arg, udp) if err != nil { return err } urlCommand := client.SegmentCommand{Type: client.URL, Arg: dst.String()} command.ChildInit = append(command.ChildInit, urlCommand) c, err := client.NewClient(command.Arg, opts.config) if err != nil { return err } id := utils.Uuid() url, err := c.CreateSegment(id, command.ChildInit, command.ChildTrig) if err != nil { return err } seg.Tail.Proto, _, seg.Tail.Hostname, seg.Tail.Port, err = utils.ParseUrl(url) if err != nil { return err } seg.ChildHost = command.Arg seg.ChildId = id return nil }
func createTunnel(host string, udp bool) (net.IP, net.IP, error) { c, err := client.NewClient(host, opts.config) if err != nil { return nil, nil, err } defer c.Close() dst, err := c.GetSrcIP(nil) tunnel := &client.Tunnel{} exists := getTunnel(dst.String()) if exists != nil { glog.Infof("Tunnel already exists: %v, %v", exists.Src, exists.Dst) // tunnel dst and src are reversed from remote tunnel.Reqid = exists.Reqid tunnel.Src = exists.Dst tunnel.Dst = exists.Src tunnel.AuthKey = exists.AuthKey tunnel.EncKey = exists.EncKey tunnel.SrcPort = exists.DstPort tunnel.SrcPort = exists.SrcPort } else { tunnel = &client.Tunnel{} if udp { var err error tunnel.DstPort, err = allocatePort() if err != nil { glog.Errorf("No ports available: %v", dst) return nil, nil, err } glog.Infof("Using %d for encap port", tunnel.DstPort) } tunnel.AuthKey = randomKey() tunnel.EncKey = randomKey() // random number between 1 and 2^32 bigreq, err := rand.Int(rand.Reader, big.NewInt(int64(^uint32(0)))) if err != nil { glog.Errorf("Failed to generate reqid: %v", err) return nil, nil, err } tunnel.Reqid = int(bigreq.Int64()) + 1 } // While tail not created for { if tunnel.Src == nil { // Select random pair of addresses from cidr for { tunnel.Dst, tunnel.Src, err = randomIPPair(opts.cidr) if err != nil { return nil, nil, err } err = reserveIP(tunnel.Dst) if err != nil { glog.Infof("IP in use: %v", tunnel.Dst) continue } err = reserveIP(tunnel.Src) if err != nil { unreserveIP(tunnel.Dst) glog.Infof("IP in use: %v", tunnel.Src) continue } break } } // create tail of tunnel var out *client.Tunnel dst, out, err = c.BuildTunnel(opts.external, tunnel) if err != nil { _, ok := err.(IPInUse) if ok { unreserveIP(tunnel.Dst) unreserveIP(tunnel.Src) tunnel.Src = nil if exists != nil { glog.Warningf("Destroying local tunnel due to remote ip conflict") destroyTunnel(dst) exists = nil } continue } glog.Errorf("Remote BuildTunnel failed: %v", err) // cleanup partial tunnel c.DestroyTunnel(opts.external) return nil, nil, err } if exists != nil && !out.Equal(tunnel) { glog.Warningf("Destroying remote mismatched tunnel") c.DestroyTunnel(opts.external) continue } tunnel = out break } // tunnel dst and src are reversed from remote tunnel.Src, tunnel.Dst = tunnel.Dst, tunnel.Src tunnel.SrcPort, tunnel.DstPort = tunnel.DstPort, tunnel.SrcPort if exists == nil { _, tunnel, err = buildTunnelLocal(dst, tunnel) if err != nil { glog.Errorf("Local buildTunnel failed: %v", err) c.DestroyTunnel(opts.external) destroyTunnel(dst) return nil, nil, err } } return tunnel.Src, tunnel.Dst, nil }