Ejemplo n.º 1
0
// Attempt to connect to cjdns
func adminConnect() (user *admin.Conn, err error) {
	// If nothing else has already set this
	var cjdnsAdmin *admin.CjdnsAdminConfig
	if AdminBind == "" || AdminPassword == "" {
		// If we still have no idea which configuration file to use
		if File == "" {
			if !userSpecifiedCjdnsadmin {
				cjdnsAdmin, err = loadCjdnsadmin()
				if err != nil {
					fmt.Println("Unable to load configuration file:", err)
					return
				}
			} else {
				cjdnsAdmin, err = readCjdnsadmin(userCjdnsadmin)
				if err != nil {
					fmt.Println("Error loading cjdnsadmin file:", err)
					return
				}
			}

			// Set the admin credentials from the .cjdnsadmin file
			//AdminPassword = cjdnsAdmin.Password
			//AdminBind = cjdnsAdmin.Addr + ":" + strconv.Itoa(cjdnsAdmin.Port)

			// If File and OutFile aren't already set, set them
			// Note that they could still be empty if the "config"
			// entry isnt in .cjdnsadmin
			if File == "" {
				File = cjdnsAdmin.Config
			}

			if OutFile == "" {
				OutFile = cjdnsAdmin.Config
			}
		} else {
			// File is set so use it
			_, err = readConfig()
			if err != nil {
				err = fmt.Errorf("Unable to load configuration file:", err.Error())
				return nil, err
			}
		}
	}
	user, err = admin.Connect(cjdnsAdmin)
	if err != nil {
		if e, ok := err.(net.Error); ok {
			if e.Timeout() {
				fmt.Println("\nConnection timed out")
			} else if e.Temporary() {
				fmt.Println("\nTemporary error (not sure what that means!)")
			} else {
				fmt.Println("\nUnable to connect to cjdns:", e)
			}
		} else {
			fmt.Println("\nError:", err)
		}
		return
	}
	return
}
Ejemplo n.º 2
0
func main() {
	fmt.Println("Hello World!")
	conn, err := admin.Connect(nil)
	if err != nil {
		fmt.Println(err)
		return
	}
	results, err := conn.InterfaceController_peerStats()
	if err != nil {
		fmt.Println(err)
		return
	}
	pretty.Print(results)

}
Ejemplo n.º 3
0
func main() {
	Pretty := pretty.Config{
		PrintStringers: true,
	}
	conn, err := admin.Connect(nil)
	if err != nil {
		fmt.Println(err)
		return
	}
	results, err := conn.InterfaceController_peerStats()
	if err != nil {
		fmt.Println(err)
		return
	}
	Pretty.Print(results)
}
Ejemplo n.º 4
0
func ConnectToCjdns() *admin.Conn {
	port, _ := strconv.ParseUint(os.Getenv("cjdns_port"), 10, 16)
	cjdnsConf := &admin.CjdnsAdminConfig{
		Addr:     os.Getenv("cjdns_addr"),
		Port:     int(port),
		Password: os.Getenv("cjdns_password"),
	}
	if cjdnsConf.Addr == "" || cjdnsConf.Port == 0 || cjdnsConf.Password == "" {
		fmt.Fprintln(os.Stderr, "failed to read CJDNS admin port configuration from environment")
		os.Exit(1)
	}

	admin, err := admin.Connect(cjdnsConf)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	return admin
}
Ejemplo n.º 5
0
func main() {
	//Define the flags, and parse them
	//Clearly a hack but it works for now
	//TODO(inhies): Re-implement flag parsing so flags can have multiple meanings based on the base command (ping, route, etc)
	if len(os.Args) <= 1 {
		usage()
		return
	} else if len(os.Args) == 2 {
		if string(os.Args[1]) == "--help" {
			fs.PrintDefaults()
			return
		}
	} else {
		fs.Parse(os.Args[2:])
	}

	//TODO(inhies): check argv[0] for trailing commands.
	//For example, to run ctraceroute:
	//ln -s /path/to/cjdcmd /usr/bin/ctraceroute like things
	command := os.Args[1]

	if AdminPassword == defaultPass {
		conf, err := config.LoadMinConfig(File)
		fmt.Printf("\nReading config file from %v\n", File)
		if err != nil || len(conf.Admin.Password) == 0 {
			fmt.Printf("Error: %v\n", err)
			return
		}

		AdminPassword = conf.Admin.Password
		AdminBind = conf.Admin.Bind
	} else {
		AdminBind = defaultAdminBind
	}

	fmt.Printf("Attempting to connect to cjdns...")
	user, err := admin.Connect(AdminBind, AdminPassword)
	if err != nil {
		if e, ok := err.(net.Error); ok {
			if e.Timeout() {
				fmt.Println("\nConnection timed out")
			} else if e.Temporary() {
				fmt.Println("\nTemporary error (not sure what that means!)")
			} else {
				fmt.Println("\nUnable to connect to cjdns:", e)
			}
		} else {
			fmt.Println("\nError:", err)
		}
		return
	}

	println("Connected")
	defer user.Conn.Close()
	arguments := fs.Args()
	data := arguments[fs.NFlag()-fs.NFlag():]

	//Setup variables now so that if the program is killed we can still finish what we're doing
	ping := &Ping{}
	var loggingStreamID string

	// capture ctrl+c
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	go func() {
		for _ = range c {
			fmt.Printf("\n")
			if command == "log" {
				//unsubscribe from logging
				_, err := admin.AdminLog_unsubscribe(user, loggingStreamID)
				if err != nil {
					fmt.Printf("%v\n", err)
					return
				}
			}
			if command == "ping" {
				//stop pinging and print results
				outputPing(ping)
			}
			//close all the channels
			for _, c := range user.Channels {
				close(c)
			}
			user.Conn.Close()
			return
		}
	}()

	switch command {

	case traceCmd:
		target, err := setTarget(data, false)
		if err != nil {
			fmt.Println(err)
			return
		}
		doTraceroute(user, target)

	case routeCmd:
		target, err := setTarget(data, true)
		if err != nil {
			fmt.Println(err)
			return
		}
		table := getTable(user)
		sort.Sort(ByQuality{table})
		count := 0
		for _, v := range table {
			if v.IP == target || v.Path == target {
				if v.Link > 1 {
					fmt.Printf("IP: %v -- Version: %d -- Path: %s -- Link: %.0f\n", v.IP, v.Version, v.Path, v.Link)
					count++
				}
			}
		}
		fmt.Println("Found", count, "routes")

	case pingCmd:
		// TODO: allow input of IP, hex path with and without dots and leading zeros, and binary path
		// TODO: allow pinging of entire routing table
		target, err := setTarget(data, true)
		if err != nil {
			fmt.Println(err)
			return
		}
		ping.Target = target
		if PingCount != defaultPingCount {
			// ping only as much as the user asked for
			for i := 1; i <= PingCount; i++ {
				err := pingNode(user, ping)
				if err != nil {
					fmt.Println(err)
					return
				}
				println(ping.Response)
			}
		} else {
			// ping until we're told otherwise
			for {
				err := pingNode(user, ping)
				if err != nil {
					fmt.Println(err)
					return
				}
				println(ping.Response)
			}
		}
		outputPing(ping)

	case logCmd:
		var response chan map[string]interface{}
		response, loggingStreamID, err = admin.AdminLog_subscribe(user, LogFile, LogLevel, LogFileLine)
		if err != nil {
			fmt.Printf("Error: %v\n", err)
			return
		}
		format := "%d %d %s %s:%d %s\n" // TODO: add user formatted output
		counter := 1
		for {
			input, ok := <-response
			if !ok {
				break
			}
			fmt.Printf(format, counter, input["time"], input["level"], input["file"], input["line"], input["message"])
			counter++
		}

	case peerCmd:
		peers := make([]*Route, 0)
		table := getTable(user)
		sort.Sort(ByQuality{table})
		fmt.Println("Finding all connected peers")

		for i := range table {

			if table[i].Link < 1 {
				continue
			}
			if table[i].RawPath == 1 {
				continue
			}
			response, err := getHops(table, table[i].RawPath)
			if err != nil {
				fmt.Println(err)
			}

			sort.Sort(ByPath{response})

			var peer *Route
			if len(response) > 1 {
				peer = response[1]
			} else {
				peer = response[0]
			}

			found := false
			for _, p := range peers {
				if p == peer {
					found = true
					break
				}
			}

			if !found {
				peers = append(peers, peer)
			}
		}
		for _, p := range peers {
			fmt.Printf("IP: %v -- Path: %s -- Link: %.0f\n", p.IP, p.Path, p.Link)
		}
	case versionCmd:
		// TODO(inhies): Ping a specific node and return it's cjdns version, or
		// ping all nodes in the routing table and get their versions
		// git log -1 --date=iso --pretty=format:"%ad" <hash>

	case killCmd:
		_, err := admin.Core_exit(user)
		if err != nil {
			fmt.Printf("%v\n", err)
			return
		}
		alive := true
		for ; alive; alive, _ = admin.SendPing(user, 1000) {
			runtime.Gosched() //play nice
		}
		println("cjdns is shutting down...")

	case dumpCmd:
		// TODO: add flag to show zero link quality routes, by default hide them
		table := getTable(user)
		sort.Sort(ByQuality{table})
		k := 1
		for _, v := range table {
			if v.Link >= 1 {
				fmt.Printf("%d IP: %v -- Version: %d -- Path: %s -- Link: %.0f\n", k, v.IP, v.Version, v.Path, v.Link)
				k++
			}
		}
	case "memory":
		println("Bye bye cjdns! This command causes a crash. Keep trying and maybe one day cjd will fix it :)")
		response, err := admin.Memory(user)
		if err != nil {
			fmt.Printf("%v\n", err)
			return
		}
		fmt.Println(response)
	default:
		fmt.Println("Invalid command", command)
		usage()
	}
}