// dispatchMsgToProtocol will dispatch this sda.Data to the right instance func (n *TreeNodeInstance) dispatchMsgToProtocol(sdaMsg *ProtocolMsg) error { // Decode the inner message here. In older versions, it was decoded before, // but first there is no use to do it before, and then every protocols had // to manually registers their messages. Since it is done automatically by // the Node, decoding should also be done by the node. var err error t, msg, err := network.UnmarshalRegisteredType(sdaMsg.MsgSlice, network.DefaultConstructors(n.Suite())) if err != nil { log.Error(n.ServerIdentity().First(), "Error while unmarshalling inner message of SDAData", sdaMsg.MsgType, ":", err) } // Put the msg into SDAData sdaMsg.MsgType = t sdaMsg.Msg = msg // if message comes from parent, dispatch directly // if messages come from children we must aggregate them // if we still need to wait for additional messages, we return msgType, msgs, done := n.aggregate(sdaMsg) if !done { log.Lvl3(n.Name(), "Not done aggregating children msgs") return nil } log.Lvlf5("TNI dispatching -Message is: %+v", sdaMsg.Msg) switch { case n.channels[msgType] != nil: log.Lvl4(n.Info(), "Dispatching to channel") err = n.DispatchChannel(msgs) case n.handlers[msgType] != nil: log.Lvl4("Dispatching to handler", n.ServerIdentity().Addresses) err = n.dispatchHandler(msgs) default: return errors.New("This message-type is not handled by this protocol") } return err }
// ReadRunFile reads from a configuration-file for a run. The configuration-file has the // following syntax: // Name1 = value1 // Name2 = value2 // [empty line] // n1, n2, n3, n4 // v11, v12, v13, v14 // v21, v22, v23, v24 // // The Name1...Namen are global configuration-options. // n1..nn are configuration-options for one run // Both the global and the run-configuration are copied to both // the platform and the app-configuration. func ReadRunFile(p Platform, filename string) []RunConfig { var runconfigs []RunConfig masterConfig := NewRunConfig() log.Lvl3("Reading file", filename) file, err := os.Open(filename) defer func() { if err := file.Close(); err != nil { log.Error("Couldn' close", file.Name()) } }() if err != nil { log.Fatal("Couldn't open file", file, err) } // Decoding of the first part of the run config file // where the config wont change for the whole set of the simulation's tests scanner := bufio.NewScanner(file) for scanner.Scan() { text := scanner.Text() log.Lvl3("Decoding", text) // end of the first part if text == "" { break } if text[0] == '#' { continue } // checking if format is good vals := strings.Split(text, "=") if len(vals) != 2 { log.Fatal("Simulation file:", filename, " is not properly formatted ( key = value )") } // fill in the general config masterConfig.Put(strings.TrimSpace(vals[0]), strings.TrimSpace(vals[1])) // also put it in platform if _, err := toml.Decode(text, p); err != nil { log.Error("Error decoding", text) } log.Lvlf5("Platform is now %+v", p) } for { scanner.Scan() if scanner.Text() != "" { break } } args := strings.Split(scanner.Text(), ", ") for scanner.Scan() { rc := masterConfig.Clone() // put each individual test configs for i, value := range strings.Split(scanner.Text(), ", ") { rc.Put(strings.TrimSpace(args[i]), strings.TrimSpace(value)) } runconfigs = append(runconfigs, *rc) } return runconfigs }
// Send opens the connection to 'dst' and sends the message 'req'. The // reply is returned, or an error if the timeout of 10 seconds is reached. func (c *Client) Send(dst *network.ServerIdentity, msg network.Body) (*network.Packet, error) { c.Lock() defer c.Unlock() if c.host == nil { kp := config.NewKeyPair(network.Suite) c.host = network.NewSecureTCPHost(kp.Secret, network.NewServerIdentity(kp.Public, "")) } // Connect to the root log.Lvl4("Opening connection to", dst) con, err := c.host.Open(dst) defer c.host.Close() if err != nil { return nil, err } m, err := network.NewNetworkMessage(msg) if err != nil { return nil, err } b, err := m.MarshalBinary() if err != nil { return nil, err } serviceReq := &ClientRequest{ Service: c.ServiceID, Data: b, } pchan := make(chan network.Packet) go func() { // send the request log.Lvlf4("Sending request %x", serviceReq.Service) if err := con.Send(context.TODO(), serviceReq); err != nil { close(pchan) return } log.Lvl4("Waiting for the response from", reflect.ValueOf(con).Pointer()) // wait for the response packet, err := con.Receive(context.TODO()) if err != nil { packet.Msg = StatusRet{err.Error()} packet.MsgType = network.TypeFromData(&StatusRet{}) } pchan <- packet }() select { case response := <-pchan: log.Lvlf5("Response: %+v %+v", response, response.Msg) // Catch an eventual error err := ErrMsg(&response, nil) if err != nil { return nil, err } return &response, nil case <-time.After(time.Second * 10): return &network.Packet{}, errors.New("Timeout on sending message") } }