Пример #1
0
func startLockServer(ctx *context.T, configDir string) (func(), error) {
	blessings, _ := v23.GetPrincipal(ctx).BlessingStore().Default()
	lockNhSuffix := fmt.Sprint(blessings)
	// Start a local mounttable where the lock server would be
	// mounted, and make this mounttable visible in the local
	// neighborhood.
	mtName, stopMT, err := locklib.StartMounttable(ctx, configDir, locklib.LockNhPrefix+lockNhSuffix)
	if err != nil {
		return nil, err
	}
	ctx, _, err = v23.WithNewNamespace(ctx, mtName)
	if err != nil {
		stopMT()
		return nil, err
	}
	ctx, cancel := context.WithCancel(ctx)
	_, server, err := v23.WithNewServer(ctx, lockObjectName(ctx), newLock(), security.DefaultAuthorizer())
	if err != nil {
		stopMT()
		return nil, err
	}
	stopLock := func() {
		cancel()
		vlog.Infof("Stopping lock server...")
		<-server.Closed()
		vlog.Infof("Stopped lock server...")
		stopMT()
	}
	vlog.Infof("Started lock server\n")
	vlog.Infof("ENDPOINT: %v\n", server.Status().Endpoints[0].Name())
	return stopLock, nil
}
Пример #2
0
func startUnclaimedLockServer(ctx *context.T, configDir string) (<-chan struct{}, func(), error) {
	// Start a local mounttable where the unclaimed lock server would
	// be mounted, and make this mounttable visible in the local
	// neighborhood.
	mtName, stopMT, err := locklib.StartMounttable(ctx, configDir, locklib.LockNhPrefix+unclaimedLockNhSuffix)
	if err != nil {
		return nil, nil, err
	}
	ctx, _, err = v23.WithNewNamespace(ctx, mtName)
	if err != nil {
		stopMT()
		return nil, nil, err
	}
	claimed := make(chan struct{})
	ctx, cancel := context.WithCancel(ctx)
	_, server, err := v23.WithNewServer(ctx, lockObjectName(ctx), newUnclaimedLock(claimed, configDir), security.AllowEveryone())
	if err != nil {
		stopMT()
		return nil, nil, err
	}
	stopUnclaimedLock := func() {
		cancel()
		vlog.Infof("Stopping unclaimed lock server...")
		<-server.Closed()
		vlog.Infof("Stopped unclaimed lock server...")
		stopMT()
	}
	vlog.Infof("Started unclaimed lock server\n")
	vlog.Infof("ENDPOINT: %v\n", server.Status().Endpoints[0].Name())
	return claimed, stopUnclaimedLock, nil
}
Пример #3
0
func (nm *V23Manager) getReadyToRun(ch chan bool) {
	defer nm.mu.Unlock()
	if nm.chatty {
		log.Printf("Calling v23.Init")
	}
	nm.ctx, nm.shutdown = v23.Init()
	if nm.shutdown == nil {
		log.Panic("shutdown nil")
	}
	if nm.chatty {
		log.Printf("Setting root to %v", nm.namespaceRoot)
	}
	v23.GetNamespace(nm.ctx).SetRoots(nm.namespaceRoot)

	nm.initialPlayerNumbers = nm.playerNumbers()
	if nm.chatty {
		log.Printf("Found %d players.", len(nm.initialPlayerNumbers))
	}
	sort.Ints(nm.initialPlayerNumbers)
	myId := 1
	if len(nm.initialPlayerNumbers) > 0 {
		myId = nm.initialPlayerNumbers[len(nm.initialPlayerNumbers)-1] + 1
	}

	if nm.isGameMaster {
		myId = 999
	}

	nm.relay = relay.MakeRelay()
	nm.myself = model.NewPlayer(myId)
	if nm.isGameMaster {
		if nm.chatty {
			log.Printf("I am game master.")
		}
		nm.isReady = true
		ch <- true
		return
	}
	if nm.chatty {
		log.Printf("I am player %v\n", nm.myself)
	}

	myName := nm.serverName(nm.Me().Id())
	if nm.chatty {
		log.Printf("Calling myself %s\n", myName)
	}
	ctx, s, err := v23.WithNewServer(nm.ctx, myName, ifc.GameServiceServer(nm.relay), MakeAuthorizer())
	if err != nil {
		log.Panic("Error creating server:", err)
		ch <- false
		return
	}
	saveEndpointToFile(s)
	nm.ctx = ctx
	nm.isReady = true
	ch <- true
}
Пример #4
0
func serve(ctx *context.T, env *cmdline.Env, args []string) error {
	name := ""
	if len(args) > 0 {
		name = args[0]
		fmt.Printf("mounting under: %s\n", name)
	}

	_, server, err := v23.WithNewServer(ctx, name, defaultMediaServer(), security.AllowEveryone())
	if err != nil {
		return err
	}
	fmt.Printf("Listening at: %s", server.Status().Endpoints[0].Name())

	<-signals.ShutdownOnSignals(ctx)
	return nil
}
Пример #5
0
func runRecvKey(ctx *context.T, env *cmdline.Env, args []string) error {
	ctx, stop, err := withLocalNamespace(ctx, "", lockUserNhName(ctx))
	if err != nil {
		return err
	}
	defer stop()

	service := &recvKeyService{
		env:    env,
		notify: make(chan error),
	}
	ctx, cancel := context.WithCancel(ctx)
	_, server, err := v23.WithNewServer(ctx, recvKeySuffix, service, security.AllowEveryone())
	if err != nil {
		return fmt.Errorf("failed to create server to receive keys: %v", err)
	}
	defer func() {
		cancel()
		<-server.Closed()
	}()
	fmt.Println("Waiting for keys")
	return <-service.notify
}
Пример #6
0
func btAndDiscoveryFunc(ctx *context.T, w io.Writer) error {
	bothf := func(ctx *context.T, w io.Writer, format string, args ...interface{}) {
		fmt.Fprintf(w, format, args...)
		ctx.Infof(format, args...)
	}
	defer bothf(ctx, w, "finishing!")

	dis, err := v23.NewDiscovery(ctx)
	if err != nil {
		bothf(ctx, w, "Can't create discovery %v", err)
		return err
	}

	ctx = v23.WithListenSpec(ctx, rpc.ListenSpec{Addrs: rpc.ListenAddrs{{Protocol: "bt", Address: "/0"}}})
	_, server, err := v23.WithNewServer(ctx, "", &echoServer{}, security.AllowEveryone())
	if err != nil {
		bothf(ctx, w, "Can't create server %v", err)
		return err
	}
	ctx.Infof("Server listening on %v", server.Status().Endpoints)
	ctx.Infof("Server listen errors: %v", server.Status().ListenErrors)

	interfaces := []string{
		"v.io/x/jni/impl/google/services/vango/Echo",
		"v.io/x/jni/impl/google/services/vango/Echo2",
		"v.io/x/jni/impl/google/services/vango/Echo3",
		"v.io/x/jni/impl/google/services/vango/Echo4",
	}
	type adstate struct {
		ad   *discovery.Advertisement
		stop func()
	}
	ads := []adstate{}
	for _, name := range interfaces {
		ad := &discovery.Advertisement{
			InterfaceName: name,
			Attributes: discovery.Attributes{
				"one":   "A value of some kind",
				"two":   "Yet another value",
				"three": "More and more",
				"four":  "This is insane",
			},
		}
		nctx, ncancel := context.WithCancel(ctx)
		ch, err := libdiscovery.AdvertiseServer(nctx, dis, server, "", ad, nil)
		if err != nil {
			bothf(nctx, w, "Can't advertise server %v", err)
			return err
		}

		stop := func() {
			ncancel()
			<-ch
		}
		ads = append(ads, adstate{ad, stop})
	}

	type updateState struct {
		ch   <-chan discovery.Update
		stop func()
	}
	var updates []updateState
	for _, name := range interfaces {
		nctx, ncancel := context.WithCancel(ctx)
		u, err := dis.Scan(nctx, `v.InterfaceName="`+name+`"`)
		if err != nil {
			bothf(nctx, w, "Can't scan %v", err)
			return err
		}
		stop := func() {
			ncancel()
		}
		updates = append(updates, updateState{u, stop})
	}

	for _, u := range updates[1:] {
		go func(up updateState) {
			for _ = range up.ch {
			}
		}(u)
	}

	makeopt := func(ad discovery.Advertisement) options.Preresolved {
		me := &naming.MountEntry{
			IsLeaf: true,
		}
		for _, a := range ad.Addresses {
			addr, _ := naming.SplitAddressName(a)
			me.Servers = append(me.Servers, naming.MountedServer{
				Server: addr,
			})
		}
		return options.Preresolved{Resolution: me}
	}

	alive := map[discovery.AdId]options.Preresolved{}
	ticker := time.NewTicker(time.Second)
	for {
		select {
		case <-ticker.C:
			if len(alive) == 0 {
				bothf(ctx, w, "No live connections to dial.")
			}
			for _, opt := range alive {
				dialtime := options.ConnectionTimeout(5 * time.Second)
				channeltime := options.ChannelTimeout(2 * time.Second)
				data := make([]byte, 1024)
				summary, err := runTimedCall(ctx, "A timed call.", string(data), opt, dialtime, channeltime)
				if err != nil {
					bothf(ctx, w, "failed call %s, %v, %v", summary, err, opt.Resolution.Servers)
				} else {
					bothf(ctx, w, "succeeded call: %s, %v", summary, opt.Resolution.Servers)
				}
			}

		case u := <-updates[0].ch:
			if u.IsLost() {
				bothf(ctx, w, "lost %v", u.Addresses())
				delete(alive, u.Id())
			} else {
				bothf(ctx, w, "found %v", u.Addresses())
				alive[u.Id()] = makeopt(u.Advertisement())
			}
		}
	}
}
Пример #7
0
// AllFunc runs a server, advertises it, scans for other servers and makes an
// Echo RPC to every advertised remote server.
func AllFunc(ctx *context.T, output io.Writer) error {
	ls := rpc.ListenSpec{Proxy: "proxy"}
	addRegisteredProto(&ls, "tcp", ":0")
	addRegisteredProto(&ls, "bt", "/0")
	fmt.Fprintf(output, "Listening on: %+v (and proxy)\n", ls.Addrs)
	ctx, server, err := v23.WithNewServer(
		v23.WithListenSpec(ctx, ls),
		mountName(ctx, "all"),
		&echoServer{},
		security.AllowEveryone())
	if err != nil {
		return err
	}
	ad := &discovery.Advertisement{
		InterfaceName: interfaceName,
		Attributes: discovery.Attributes{
			"Hello": "There",
		},
	}
	d, err := v23.NewDiscovery(ctx)
	if err != nil {
		return err
	}
	stoppedAd, err := libdiscovery.AdvertiseServer(ctx, d, server, "", ad, nil)
	if err != nil {
		return err
	}
	updates, err := d.Scan(ctx, "v.InterfaceName=\""+interfaceName+"\"")
	if err != nil {
		return err
	}
	var (
		status      = server.Status()
		counter     = 0
		peerByAdId  = make(map[discovery.AdId]*peer)
		lastCall    = make(map[discovery.AdId]time.Time)
		callResults = make(chan string)
		activeCalls = 0
		quit        = false
		myaddrs     = serverAddrs(status)
		ticker      = time.NewTicker(time.Second)
		call        = func(p *peer) {
			counter++
			activeCalls++
			lastCall[p.adId] = time.Now()
			go func(msg string) {
				summary, err := p.call(ctx, msg)
				if err != nil {
					ctx.Infof("Failed to call [%v]: %v", p.description, err)
					callResults <- ""
					return
				}
				callResults <- summary
			}(fmt.Sprintf("Hello #%d", counter))
		}
		statRequest = make(chan chan<- string)
	)
	defer ticker.Stop()
	stats.NewStringFunc(vangoStat, func() string {
		r := make(chan string)
		statRequest <- r
		return <-r
	})
	defer stats.Delete(vangoStat)
	fmt.Fprintln(output, "My AdID:", ad.Id)
	fmt.Fprintln(output, "My addrs:", myaddrs)
	ctx.Infof("SERVER STATUS: %+v", status)
	for !quit {
		select {
		case <-ctx.Done():
			quit = true
		case <-status.Dirty:
			status = server.Status()
			newaddrs := serverAddrs(status)
			changed := len(newaddrs) != len(myaddrs)
			if !changed {
				for i := range newaddrs {
					if newaddrs[i] != myaddrs[i] {
						changed = true
						break
					}
				}
			}
			if changed {
				myaddrs = newaddrs
				fmt.Fprintln(output, "My addrs:", myaddrs)
			}
			ctx.Infof("SERVER STATUS: %+v", status)
		case u, scanning := <-updates:
			if !scanning {
				fmt.Fprintln(output, "SCANNING STOPPED")
				quit = true
				break
			}
			if u.IsLost() {
				if p, ok := peerByAdId[u.Id()]; ok {
					fmt.Fprintln(output, "LOST:", p.description)
				}
				delete(peerByAdId, u.Id())
				delete(lastCall, u.Id())
				break
			}
			p, err := newPeer(ctx, u)
			if err != nil {
				ctx.Info(err)
				break
			}
			peerByAdId[p.adId] = p
			fmt.Fprintln(output, "FOUND:", p.description)
			call(p)
		case r := <-callResults:
			activeCalls--
			if len(r) > 0 {
				fmt.Fprintln(output, r)
			}
		case <-stoppedAd:
			fmt.Fprintln(output, "STOPPED ADVERTISING")
			stoppedAd = nil
		case <-ticker.C:
			// Call all peers that haven't been called in a while
			now := time.Now()
			for id, t := range lastCall {
				if now.Sub(t) > rpcTimeout {
					call(peerByAdId[id])
				}
			}
		case s := <-statRequest:
			idx := 1
			ret := new(bytes.Buffer)
			fmt.Fprintln(ret, "ACTIVE CALLS:", activeCalls)
			fmt.Fprintln(ret, "PEERS")
			for id, p := range peerByAdId {
				fmt.Fprintf(ret, "%2d) %s -- %v\n", idx, p.description, lastCall[id])
			}
			s <- ret.String()
		}
	}
	fmt.Println(output, "EXITING: Cleaning up")
	for activeCalls > 0 {
		<-callResults
		activeCalls--
	}
	// Exhaust the scanned updates queue.
	// (The channel will be closed as a by-product of the context being Done).
	for range updates {
	}
	fmt.Fprintln(output, "EXITING: Done")
	return nil
}
Пример #8
0
func (nm *networkManager) run(ready chan<- interface{}, newLeftScreen, newRightScreen chan<- chan<- *spec.Triangle, newInvite chan<- Invitation) {
	defer close(nm.myScreen)
	defer close(newLeftScreen)
	defer close(newRightScreen)
	notifyReady := func(result interface{}) {
		ready <- result
		close(ready)
		ready = nil
	}
	ctx, shutdown := v23.Init()
	defer shutdown()
	ctx, server, err := v23.WithNewServer(ctx, "", spec.ScreenServer(nm), security.AllowEveryone())
	if err != nil {
		notifyReady(err)
		return
	}
	disc, err := v23.NewDiscovery(ctx)
	if err != nil {
		notifyReady(err)
		return
	}
	// Select a color based on some unique identifier of the process, the PublicKey serves as one.
	notifyReady(selectColor(v23.GetPrincipal(ctx).PublicKey()))
	var (
		left     = remoteScreen{myScreen: nm.myScreen, notify: newLeftScreen}
		right    = remoteScreen{myScreen: nm.myScreen, notify: newRightScreen}
		accepted = make(chan string) // Names of remote screens that accepted an invitation
		seek     = make(chan bool)   // Send false to stop seeking invitations from others, true otherwise

		pendingInviterName        string
		pendingInviteUserResponse <-chan error
		pendingInviteRPCResponse  chan<- error
	)
	seekInvites(ctx, disc, server, seek)
	go sendInvites(ctx, disc, accepted)
	for {
		select {
		case invitation := <-nm.inviteRPCs:
			if left.Active() {
				invitation.Response <- fmt.Errorf("thanks for the invite but I'm already engaged with a previous invitation")
				break
			}
			// Defer the response to the user interface.
			ch := make(chan error)
			pendingInviterName = invitation.Name
			pendingInviteRPCResponse = invitation.Response
			pendingInviteUserResponse = ch
			invitation.Response = ch
			newInvite <- invitation
		case err := <-pendingInviteUserResponse:
			pendingInviteRPCResponse <- err
			if err == nil {
				ctx.Infof("Activating left screen %q", pendingInviterName)
				left.Activate(ctx, pendingInviterName)
				seek <- false
			}
			pendingInviterName = ""
			pendingInviteUserResponse = nil
			pendingInviteRPCResponse = nil
		case <-left.Lost():
			ctx.Infof("Deactivating left screen")
			left.Deactivate()
			seek <- true
		case invitee := <-accepted:
			ctx.Infof("Activating right screen %q", invitee)
			right.Activate(ctx, invitee)
		case <-right.Lost():
			ctx.Infof("Deactivating right screen")
			right.Deactivate()
			go sendInvites(ctx, disc, accepted)
		case <-ctx.Done():
			return
		}
	}
}
Пример #9
0
func main() {
	ctx, shutdown := v23.Init()
	defer shutdown()

	// Run server
	if *to == "" {
		// We are not the caller, so make the RPC available for the
		// caller to call in on.
		bsrv := ifc.BridgeServer(makeImpl())
		_, server, err := v23.WithNewServer(ctx, *serviceName, bsrv,
			security.DefaultAuthorizer())

		if err != nil {
			ctx.Error("Error serving service: ", err)
			return
		}

		endpoint := server.Status().Endpoints[0]
		fmt.Printf("Listening at: %v\n", endpoint)

		// Wait forever.
		<-signals.ShutdownOnSignals(ctx)
	} else if *to != "" && *from != "" {
		// pipe mode
		ifct := ifcTopics(*topics)
		tmout := options.ChannelTimeout(*timeout)

		leftc := ifc.BridgeClient(*to)
		rightc := ifc.BridgeClient(*from)

		leftcc, err := leftc.Link(ctx, ifct, tmout)
		if err != nil {
			ctx.Error(err)
			return
		}

		rightcc, err := rightc.Link(ctx, ifct, tmout)
		if err != nil {
			ctx.Error(err)
			return
		}

		errCh := make(chan error, 2)

		wg := &sync.WaitGroup{}
		wg.Add(2)
		go linkToLink(leftcc.RecvStream(), rightcc.SendStream(), errCh, wg)
		go linkToLink(rightcc.RecvStream(), leftcc.SendStream(), errCh, wg)
		wg.Wait()
		select {
		case err := <-errCh:
			log.Print("pipe error: ", err)
		default:
			// don't block on channel read
		}
	} else {
		cc, mu, err := mqttConnect()
		if err != nil {
			ctx.Error("mqtt connect: ", err)
			return
		}

		bc := ifc.BridgeClient(*to)

		ifct := ifcTopics(*topics)
		bcc, err := bc.Link(ctx, ifct, options.ChannelTimeout(*timeout))
		if err != nil {
			ctx.Error(err)
			return
		}

		done := make(chan error, 2)
		go func() {
			done <- transmitter(ifct, bcc.SendStream(), cc, mu)
			println("send done")
		}()
		go func() {
			done <- receiver(bcc.RecvStream(), cc, mu)
			println("recv done")
		}()
		err = <-done
		log.Print("Stopped with error ", err)

		// Stop sender by closing cc.Incoming
		cc.Disconnect()
	}
}