func serve(transportPublic api.Transport, transportAdmin api.Transport, node api.Node, listenPublic string, listenAdmin string) { node.SetPolicy( policy.NewServer(transportPublic, listenPublic, false), policy.NewServer(transportAdmin, listenAdmin, true)) log.Println("Public Server starting: ", listenPublic) log.Println("Control Server starting: ", listenAdmin) node.Start() }
// pollServer will keep trying until either we get a result or the timeout expires func (p *Poll) pollServer(transport api.Transport, node api.Node, host string, pubsrv bc.PubKey) (bool, error) { // Pickup Local rpubkey, err := transport.RPC(host, "ID") if err != nil { return false, err } rpk := pubsrv.Clone() if err := rpk.FromB64(string(rpubkey)); err != nil { return false, err } toRemoteRaw, err := node.Pickup(rpk, p.lastPollLocal) if err != nil { return false, err } // Pickup Remote toLocalRaw, err := transport.RPC(host, "Pickup", pubsrv.ToB64(), strconv.FormatInt(p.lastPollRemote, 10)) if err != nil { return false, err } var toLocal api.Bundle if err := json.Unmarshal(toLocalRaw, &toLocal); err != nil { return false, err } p.lastPollLocal = toRemoteRaw.Time p.lastPollRemote = toLocal.Time toRemote, err := json.Marshal(toRemoteRaw) if err != nil { return false, err } // Dropoff Remote if len(toRemoteRaw.Data) > 0 { if _, err := transport.RPC(host, "Dropoff", string(toRemote)); err != nil { return false, err } } // Dropoff Local if len(toLocal.Data) > 0 { if err := node.Dropoff(toLocal); err != nil { return false, err } } return true, nil }
func (r *DefaultRouter) check(node api.Node, pubkey bc.PubKey, channelName string, idx uint16, nonce []byte, message []byte) (bool, error) { hash, err := bc.DestHash(pubkey, nonce) if err != nil { return false, err } hashLen := uint16(len(hash)) nonceHash := message[idx+16 : idx+16+hashLen] if bytes.Equal(hash, nonceHash) { // named channel key match if err := node.Handle(channelName, message[idx+16+hashLen:]); err != nil { return false, err } return true, nil } return false, nil }
func (r *DefaultRouter) forward(node api.Node, channelName string, message []byte) error { for _, p := range r.Patches { //todo: this could be constant-time if channelName == p.From { for i := 0; i < len(p.To); i++ { if err := node.Forward(p.To[i], message); err != nil { return err } } return nil } } if err := node.Forward(channelName, message); err != nil { return err } return nil }
func (Module) handleResponse(w http.ResponseWriter, r *http.Request, node api.Node, adminMode bool) { var a api.RemoteCall decoder := json.NewDecoder(r.Body) err := decoder.Decode(&a) if err != nil { log.Println(err.Error()) } var result string if adminMode { result, err = node.AdminRPC(a.Action, a.Args...) } else { result, err = node.PublicRPC(a.Action, a.Args...) } if err != nil { log.Println(err.Error()) } else if len(result) < 1 { result = "OK" // todo: for backwards compatability, remove when nothing needs it } w.Write([]byte(result)) }
// Route - Router that does default behavior func (r *DefaultRouter) Route(node api.Node, message []byte) error { // Stuff Everything will need just about every time... // var channelLen uint16 // beginning uint16 of message is channel name length channelName := "" channelLen = (uint16(message[0]) << 8) | uint16(message[1]) if len(message) < int(channelLen)+2+16+16 { // uint16 + nonce + hash //todo return errors.New("Incorrect channel name length") } idx := 2 + channelLen //skip over the channel name nonce := message[idx : idx+16] if r.seenRecently(nonce) { // LOOP PREVENTION before handling or forwarding return nil } cid, err := node.CID() // we need this for cloning if err != nil { return err } // // When the channel tag is set... if channelLen > 0 { // channel message channelName = string(message[2 : 2+channelLen]) consumed := false if r.CheckChannels { chn, err := node.GetChannel(channelName) if err == nil { // this is a channel key we know pubkey := cid.Clone() pubkey.FromB64(chn.Pubkey) consumed, err = r.check(node, pubkey, channelName, idx, nonce, message) if err != nil { return err } } } if (!consumed && r.ForwardUnknownChannels) || (consumed && r.ForwardConsumedChannels) { if err := r.forward(node, channelName, message); err != nil { return err } } } else { // private message (zero length channel) // content key case (to be removed, deprecated) consumed := false if r.CheckContent { consumed, err = r.check(node, cid, channelName, idx, nonce, message) if err != nil { return err } } if (!consumed && r.ForwardUnknownContent) || (consumed && r.ForwardConsumedContent) { if err := r.forward(node, channelName, message); err != nil { return err } } // profile keys case consumed = false if r.CheckProfiles { profiles, err := node.GetProfiles() if err != nil { return err } for _, profile := range profiles { if !profile.Enabled { continue } pubkey := cid.Clone() pubkey.FromB64(profile.Pubkey) consumed, err = r.check(node, pubkey, channelName, idx, nonce, message) if err != nil { return err } if consumed { break } } } if (!consumed && r.ForwardUnknownProfiles) || (consumed && r.ForwardConsumedProfiles) { if err := r.forward(node, channelName, message); err != nil { return err } } } return nil }