Пример #1
0
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()
	}
}
Пример #2
0
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
}
Пример #3
0
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("")
	}
}
Пример #4
0
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
	}
}
Пример #5
0
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
}
Пример #6
0
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
}