예제 #1
0
// KiSSAnonHandshake does a named KiSS handshake over the given transport,
// validating the other end using the given verifier, which may be nil.
//
// Usually, clients use the anonymous handshake, while servers use the named handshake.
func KiSSNamedHandshake(identity natrium.EdDSAPrivate, check Verifier, transport io.ReadWriteCloser) (io.ReadWriteCloser, error) {
	eph_priv := natrium.ECDHGenerateKey()
	signat := identity.Sign(eph_priv.PublicKey())

	// send NHLO message
	tosend := kissNamedHello{eph_priv.PublicKey(), signat, identity.PublicKey()}
	buf := new(bytes.Buffer)
	err := struc.Pack(buf, &tosend)
	if err != nil {
		panic(err.Error())
	}
	packaged := kissSegment{0, kiss_NHLO, buf.Bytes()}

	return kissFinishHandshake(eph_priv, packaged, check, transport)
}
예제 #2
0
func newServGroup(aidee natrium.EdDSAPrivate) (*servGroup, error) {
	ambass := make([]*kiricom.ServerCtx, 8)
	toret := new(servGroup)
	toret.ambass = ambass
	toret.deadch = make(chan bool)
	toret.wirech = make(chan io.ReadWriteCloser)
	toret.once = new(sync.Once)
	toret.aidee = aidee

	// contact all the ambassadors
	for i := 0; i < 8; i++ {
		haha, err := toret.connAmb(i)
		if err != nil && err != core2core.ErrRejectedReq {
			for j := 0; j < i; j++ {
				if ambass[j] != nil {
					ambass[j].Close()
				}
			}
			return nil, err
		}
		ambass[i] = haha
	}
	kilog.Debug("serv: all ambassadors of %v notified", aidee.PublicKey())

	// spin off a thread to update ambassadors from time to time
	go func() {
		for {
			time.Sleep(time.Minute * 20)
		FAST:
			time.Sleep(time.Second)
			allbad := true
			for _, v := range ambass {
				if v != nil {
					allbad = false
					break
				}
			}

			if allbad {
				kilog.Warning("serv: ambassadors ALL BAD!")
				for i := 0; i < 8; i++ {
					toret.revAmbass(i)
				}
				continue
			}

			// pick a random ambassador, kill, and resurrect
			// TODO do something more graceful here
			num := rand.Int() % len(ambass)
			kilog.Debug("serv: ambassador %v of %v condemned", num, aidee.PublicKey())
			condemned := ambass[num]
			if condemned != nil {
				kilog.Debug("serv: actually executed condemnation")
				condemned.Close()
			} else {
				goto FAST
			}
		}
	}()

	// spin up threads to handle incoming connections
	for i, lol := range ambass {
		lol := lol
		i := i
		if lol != nil {
			go toret.runAmbass(i, lol)
		}
	}
	// return
	return toret, nil
}