// 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) }
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 }