// NewHost starts a new Host that will listen on the network for incoming // messages. It will store the private-key. func NewHost(e *network.ServerIdentity, pkey abstract.Scalar) *Host { h := &Host{ ServerIdentity: e, workingAddress: e.First(), connections: make(map[network.ServerIdentityID]network.SecureConn), pendingTreeMarshal: make(map[RosterID][]*TreeMarshal), pendingSDAs: make([]*ProtocolMsg, 0), host: network.NewSecureTCPHost(pkey, e), private: pkey, suite: network.Suite, networkChan: make(chan network.Packet, 1), isClosing: false, ProcessMessagesQuit: make(chan bool), } h.overlay = NewOverlay(h) h.serviceStore = newServiceStore(h, h.overlay) return h }
func TestServiceBackForthProtocol(t *testing.T) { local := sda.NewLocalTest() defer local.CloseAll() // register service sda.RegisterNewService("BackForth", func(c *sda.Context, path string) sda.Service { return &simpleService{ ctx: c, } }) // create hosts hosts, el, _ := local.GenTree(4, true, true, false) // create client priv, pub := sda.PrivPub() client := network.NewSecureTCPHost(priv, network.NewServerIdentity(pub, "")) c, err := client.Open(hosts[0].ServerIdentity) assert.Nil(t, err) // create request r := &simpleRequest{ ServerIdentities: el, Val: 10, } buff, err := network.MarshalRegisteredType(r) assert.Nil(t, err) req := &sda.ClientRequest{ Service: sda.ServiceFactory.ServiceID("BackForth"), Data: buff, } assert.Nil(t, c.Send(context.TODO(), req)) nm, err := c.Receive(context.TODO()) assert.Nil(t, err) assert.Equal(t, nm.MsgType, simpleResponseType) resp := nm.Msg.(simpleResponse) assert.Equal(t, resp.Val, 10) }
// 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") } }