Пример #1
0
func runCore(id directory.Client) {
	state := core2core.NewNodeState(dirProvider, id)

	addr := id.GetAddress()
	srv, err := kiricom.EasyListen(fmt.Sprintf("0.0.0.0:%v", addr.Port), nil, id.GetSecret())
	if err != nil {
		panic(err.Error())
	}

	err = dirProvider.JoinCore(id)
	if err != nil {
		panic(err.Error())
	}

	go func() {
		for {
			time.Sleep(time.Minute * 5)
			err = dirProvider.JoinCore(id)
			if err != nil {
				kilog.Warning("core: error while joining %v", err.Error())
			}
		}
	}()

	fmt.Println(id.GetAddress())

	kilog.Info("started core service on %v", addr)
	for {
		client, err := srv.Accept()
		if err != nil {
			panic(err.Error())
		}
		kilog.Debug("core: accepted a client")
		go func() {
			err := state.HandleClient(client)
			if err != nil {
				kilog.Warning("core: error %v", err)
			}
		}()
	}
}
Пример #2
0
func handleControl(clnt io.ReadWriteCloser) {
	defer clnt.Close()
	greeting := ctlGreeting{0xCACACACA, ctlVersion{0, 0, 0}, socksPort} // 0.0.0 means unnumbered version
	err := struc.Pack(clnt, &greeting)
	if err != nil {
		kilog.Debug("unable to write control greeting: %v", err.Error())
		return
	}
	var command ctlCommand
	err = struc.Unpack(clnt, &command)
	if err != nil {
		kilog.Debug("unable to read control command: %v", err.Error())
		return
	}

	var response ctlResponse
	defer struc.Pack(clnt, &response)

	// do the actual work
	switch command.Verb {
	case ctlCmdNOOP:
		return
	case ctlCmdHOST:
		kilog.Debug("received control request to forward port %v to %v, with %v",
			command.IntPort, command.ExtPort, command.PrivKey)
		ctlState.RLock()
		_, ok := ctlState.prt2prv[command.ExtPort]
		ctlState.RUnlock()
		if ok {
			kilog.Debug("port %v already occupied, refusing request!", command.ExtPort)
			response.Verb = ctlRespNOPE
			response.Name = "port already occupied"
			return
		}
		ctlState.Lock()
		defer ctlState.Unlock()
		newlistnr, err := kiricom.EasyListen(fmt.Sprintf("0.0.0.0:%v", command.ExtPort), command.PrivKey,
			command.PrivKey.PublicKey())
		kilog.Debug("startControl secret is %x", command.PrivKey.PublicKey())
		if err != nil {
			kilog.Debug("could not create ICOM listener")
			response.Verb = ctlRespNOPE
			response.Name = err.Error()
			return
		}
		ctlState.prt2lst[command.ExtPort] = newlistnr
		ctlState.prt2prv[command.ExtPort] = command.PrivKey
		response.Verb = ctlRespOKAY
		pubip, err := getPublicIP()
		if err != nil {
			kilog.Critical("computer does not seem to have an Internet connection; dying!")
			os.Exit(-1)
		}
		response.Name = sagiriNames.EdgeID{command.PrivKey.PublicKey(), pubip,
			uint16(command.ExtPort)}.String()

		groop, err := newServGroup(command.PrivKey)
		if err != nil {
			kilog.Debug("host: could not start servGroup %v", err.Error())
			return
		}

		// time to spin off threads to forward the connections
		handle := func(clnt io.ReadWriteCloser) {
			defer clnt.Close()
			fwd, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%v", command.IntPort))
			if err != nil {
				kilog.Debug("host: could not forward %v", err.Error())
				return
			}
			kilog.Debug("host: completed forwarding")
			defer fwd.Close()
			go func() {
				defer fwd.Close()
				defer clnt.Close()
				io.Copy(fwd, clnt)
			}()
			io.Copy(clnt, fwd)
		}

		go func() {
			defer newlistnr.Close()
			defer groop.Destroy()
			for {
				clnt, err := newlistnr.Accept()
				if err != nil {
					kilog.Debug("host: direct error %v", err.Error())
					return
				}
				go handle(clnt)
			}
		}()

		go func() {
			defer groop.Destroy()
			defer newlistnr.Close()
		REDO:
			for {
				clnt, err := groop.Accept()
				if err != nil {
					kilog.Debug("host: onion error %v", err.Error())
					groop.Destroy()
					groop, err = newServGroup(command.PrivKey)
					if err != nil {
						kilog.Debug(err.Error())
						time.Sleep(time.Second)
					}
					goto REDO
				}
				go handle(clnt)
			}
		}()
	case ctlCmdSTOP:
		ctlState.Lock()
		defer ctlState.Unlock()
		_, ok := ctlState.prt2lst[command.ExtPort]
		if !ok {
			response.Verb = ctlRespNOPE
			response.Name = "no service with the given port"
			return
		}
		rlPriv := ctlState.prt2prv[command.ExtPort]
		if subtle.ConstantTimeCompare(rlPriv, command.PrivKey) != 1 {
			response.Verb = ctlRespNOPE
			response.Name = "given private key incorrect, refusing to remove"
			return
		}
		delete(ctlState.prt2prv, command.ExtPort)
		ctlState.prt2lst[command.ExtPort].Close()
		response.Verb = ctlRespOKAY
	}
}
Пример #3
0
func TestDirectoryCoreEdge(t *testing.T) {
	spinTestDir()
	defer stopTestDir()

	for i := 0; i < 10; i++ {
		//time.Sleep(time.Second)
		clnt := directory.NewClient(natrium.EdDSAGenerateKey())
		prv := directory.DefaultProvider("127.0.0.1:12345")

		addr, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:0")
		__lol, err := net.ListenTCP("tcp", addr)
		if err != nil {
			panic(err.Error())
		}
		clnt.SetAddress(__lol.Addr().(*net.TCPAddr))
		addr = __lol.Addr().(*net.TCPAddr)
		__lol.Close()

		lol, err := kiricom.EasyListen(addr.String(), nil, clnt.GetSecret())
		if err != nil {
			panic(err.Error())
		}
		defer lol.Close()

		state := NewNodeState(prv, clnt)

		go func() {
			for {
				clnt, err := lol.Accept()
				if err != nil {
					return
				}
				go func() {
					defer clnt.Close()
					err := state.HandleClient(clnt)
					if err != nil {
						kilog.Debug(err.Error())
					}
				}()
			}
		}()

		err = prv.JoinCore(clnt)
		if err != nil {
			log.Fatal(err.Error())
		}
	}

	time.Sleep(time.Second * 2)
	clnt := directory.NewClient(natrium.EdDSAGenerateKey())
	prv := directory.DefaultProvider("127.0.0.1:12345")

	neiz, err := prv.JoinEdge(clnt)
	if err != nil {
		panic(err.Error())
	}
	fmt.Println(neiz)

	// route in a circle
	func() {
		spider, err := NewClient(neiz[0])
		if err != nil {
			panic(err.Error())
		}
		defer spider.Destroy()
		for i := 0; i < 11; i++ {
			fmt.Println(spider.curpk)
			lawl, err := spider.ListNeighs()
			if err != nil {
				panic(err.Error())
			}
			err = spider.ConnectNext(lawl[0])
			if err != nil {
				panic(err.Error())
			}
			//time.Sleep(time.Second)
		}
	}()

	fmt.Println("--- ROUTING DONE ---")

	// time to test ambassadors!
	func() {
		alpha, err := NewClient(neiz[0])
		if err != nil {
			panic(err.Error())
		}
		beta, err := NewClient(neiz[0])
		if err != nil {
			panic(err.Error())
		}
		defer alpha.Destroy()
		defer beta.Destroy()

		// alpha registers, beta connects
		id := natrium.EdDSAGenerateKey()
		srv, err := alpha.RegAmbassador(id.PublicKey())
		if err != nil {
			panic(err.Error())
		}
		clnt, err := beta.ConnAmbassador(id.PublicKey())
		if err != nil {
			panic(err.Error())
		}

		// throwaway echo server
		go func() {
			lol, err := srv.Accept()
			if err != nil {
				panic(err.Error())
			}
			defer lol.Close()
			io.Copy(lol, lol)
		}()

		// test with random stuff
		xaxa := make([]byte, 16)
		rand.Read(xaxa)

		sok, err := clnt.Dial()
		if err != nil {
			panic(err.Error())
		}
		sok.Write(xaxa)
		resp := make([]byte, 16)
		io.ReadFull(sok, resp)
		fmt.Printf("%x\n", xaxa)
		fmt.Printf("%x\n", resp)
		if subtle.ConstantTimeCompare(resp, xaxa) != 1 {
			t.Fatal("ambassador broken")
		}
	}()
	fmt.Println("--- AMBASSADOR DONE ---")
}