Esempio n. 1
0
// StartProfiling will create a .prof file to analyze p2p app performance
func StartProfiling(profile string) {

	pwd, err := os.Getwd()
	if err != nil {
		ptp.Log(ptp.Error, "Getwd() error : %v", err)
		return
	}

	timeStr := "cpu"
	if profile == "cpu" {
		fileName := fmt.Sprintf("%s/%s.prof", pwd, timeStr)
		f, err := os.Create(fileName)
		if err != nil {
			ptp.Log(ptp.Error, "Create cpu_prof file failed. %v", err)
			return
		}
		ptp.Log(ptp.Info, "Start cpu profiling to file %s", fileName)
		pprof.StartCPUProfile(f)
	} else if profile == "memory" {
		_, err := os.Create(fmt.Sprintf("%s/%s.p2p_mem_prof", pwd, timeStr))
		if err != nil {
			ptp.Log(ptp.Error, "Create mem_prof file failed. %v", err)
			return
		}
	}
}
Esempio n. 2
0
// Daemon starts P2P daemon
func Daemon(port, sFile, profiling string) {
	StartProfiling(profiling)
	ptp.InitPlatform()
	instances = make(map[string]instance)
	ptp.InitErrors()

	if !ptp.CheckPermissions() {
		os.Exit(1)
	}

	proc := new(Procedures)
	rpc.Register(proc)
	rpc.HandleHTTP()
	listen, err := net.Listen("tcp", "localhost:"+port)
	if err != nil {
		ptp.Log(ptp.Error, "Cannot start RPC listener %v", err)
		os.Exit(1)
	}

	if sFile != "" {
		saveFile = sFile
		ptp.Log(ptp.Info, "Restore file provided")
		// Try to restore from provided file
		instances, err := loadInstances(saveFile)
		if err != nil {
			ptp.Log(ptp.Error, "Failed to load instances: %v", err)
		} else {
			ptp.Log(ptp.Info, "%d instances were loaded from file", len(instances))
			for _, inst := range instances {
				resp := new(Response)
				proc.Run(&inst, resp)
			}
		}
	}

	ptp.Log(ptp.Info, "Starting RPC Listener on %s port", port)
	go http.Serve(listen, nil)

	// Capture SIGINT
	// This is used for development purposes only, but later we should consider updating
	// this code to handle signals
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)

	go func() {
		for sig := range c {
			fmt.Println("Received signal: ", sig)
			pprof.StopCPUProfile()
			os.Exit(0)
		}
	}()
	select {}
}
Esempio n. 3
0
// SetLog modifies specific option
func (p *Procedures) SetLog(args *NameValueArg, resp *Response) error {
	ptp.Log(ptp.Info, "Setting option %s to %s", args.Name, args.Value)
	resp.ExitCode = 0
	if args.Name == "log" {
		resp.Output = "Logging level has switched to " + args.Value + " level"
		if args.Value == "DEBUG" {
			ptp.SetMinLogLevel(ptp.Debug)
		} else if args.Value == "INFO" {
			ptp.SetMinLogLevel(ptp.Info)
		} else if args.Value == "TRACE" {
			ptp.SetMinLogLevel(ptp.Trace)
		} else if args.Value == "WARNING" {
			ptp.SetMinLogLevel(ptp.Warning)
		} else if args.Value == "ERROR" {
			ptp.SetMinLogLevel(ptp.Error)
		} else {
			resp.ExitCode = 1
			resp.Output = "Unknown log level was specified. Supported log levels is:\n"
			resp.Output = resp.Output + "TRACE\n"
			resp.Output = resp.Output + "DEBUG\n"
			resp.Output = resp.Output + "INFO\n"
			resp.Output = resp.Output + "WARNING\n"
			resp.Output = resp.Output + "ERROR\n"
		}
	}
	return nil
}
Esempio n. 4
0
// Dial connects to a local RPC server
func Dial(port string) *rpc.Client {
	client, err := rpc.DialHTTP("tcp", "localhost:"+port)
	if err != nil {
		ptp.Log(ptp.Error, "Failed to connect to RPC %v", err)
		os.Exit(1)
	}
	return client
}
Esempio n. 5
0
func encodeInstances() ([]byte, error) {
	var savedInstances []RunArgs
	instances_mut.Lock()
	for _, inst := range instances {
		savedInstances = append(savedInstances, inst.Args)
	}
	instances_mut.Unlock()
	runtime.Gosched()
	b := bytes.Buffer{}
	e := gob.NewEncoder(&b)
	err := e.Encode(savedInstances)
	if err != nil {
		ptp.Log(ptp.Error, "Failed to encode instances: %v", err)
		return []byte(""), err
	}
	return b.Bytes(), nil
}
Esempio n. 6
0
// Run starts a P2P instance
func (p *Procedures) Run(args *RunArgs, resp *Response) error {
	resp.ExitCode = 0
	resp.Output = "Running new P2P instance for " + args.Hash + "\n"

	// Validate if interface name is unique
	if args.Dev != "" {
		instances_mut.Lock()
		for _, inst := range instances {
			if inst.PTP.DeviceName == args.Dev {
				resp.ExitCode = 1
				resp.Output = "Device name is already in use"
				instances_mut.Unlock()
				runtime.Gosched()
				return errors.New(resp.Output)
			}
		}
		instances_mut.Unlock()
		runtime.Gosched()
	}

	var exists bool
	instances_mut.Lock()
	_, exists = instances[args.Hash]
	instances_mut.Unlock()
	runtime.Gosched()
	if !exists {
		resp.Output = resp.Output + "Lookup finished\n"
		if args.Key != "" {
			if len(args.Key) < 16 {
				args.Key += "0000000000000000"[:16-len(args.Key)]
			} else if len(args.Key) > 16 && len(args.Key) < 24 {
				args.Key += "000000000000000000000000"[:24-len(args.Key)]
			} else if len(args.Key) > 24 && len(args.Key) < 32 {
				args.Key += "00000000000000000000000000000000"[:32-len(args.Key)]
			} else if len(args.Key) > 32 {
				args.Key = args.Key[:32]
			}
		}

		var newInst instance
		newInst.ID = args.Hash
		newInst.Args = *args
		ptpInstance := ptp.StartP2PInstance(args.IP, args.Mac, args.Dev, "", args.Hash, args.Dht, args.Keyfile, args.Key, args.TTL, "", args.Fwd, args.Port)
		if ptpInstance == nil {
			resp.Output = resp.Output + "Failed to create P2P Instance"
			resp.ExitCode = 1
			return errors.New("Failed to create P2P Instance")
		}
		ptp.Log(ptp.Info, "Instance created")
		newInst.PTP = ptpInstance
		instances_mut.Lock()
		instances[args.Hash] = newInst
		instances_mut.Unlock()
		runtime.Gosched()
		go ptpInstance.Run()
		if saveFile != "" {
			resp.Output = resp.Output + "Saving instance into file"
			saveInstances(saveFile)
		}
	} else {
		resp.Output = resp.Output + "Hash already in use\n"
	}
	return nil
}