func main() { lbbroker := &lbbroker_t{} lbbroker.frontend, _ = zmq.NewSocket(zmq.ROUTER) lbbroker.backend, _ = zmq.NewSocket(zmq.ROUTER) defer lbbroker.frontend.Close() defer lbbroker.backend.Close() lbbroker.frontend.Bind("ipc://frontend.ipc") lbbroker.backend.Bind("ipc://backend.ipc") for client_nbr := 0; client_nbr < NBR_CLIENTS; client_nbr++ { go client_task() } for worker_nbr := 0; worker_nbr < NBR_WORKERS; worker_nbr++ { go worker_task() } // Queue of available workers lbbroker.workers = make([]string, 0, 10) // Prepare reactor and fire it up lbbroker.reactor = zmq.NewReactor() lbbroker.reactor.AddSocket(lbbroker.backend, zmq.POLLIN, func(e zmq.State) error { return handle_backend(lbbroker) }) lbbroker.reactor.Run(-1) }
func New(primary bool, local, remote string) (bstar *Bstar, err error) { bstar = &Bstar{} // Initialize the Binary Star bstar.Reactor = zmq.NewReactor() if primary { bstar.state = state_PRIMARY } else { bstar.state = state_BACKUP } // Create publisher for state going to peer bstar.statepub, err = zmq.NewSocket(zmq.PUB) bstar.statepub.Bind(local) // Create subscriber for state coming from peer bstar.statesub, err = zmq.NewSocket(zmq.SUB) bstar.statesub.SetSubscribe("") bstar.statesub.Connect(remote) // Set-up basic reactor events bstar.Reactor.AddChannelTime(time.Tick(bstar_HEARTBEAT), 1, func(i interface{}) error { return bstar.send_state() }) bstar.Reactor.AddSocket(bstar.statesub, zmq.POLLIN, func(e zmq.State) error { return bstar.recv_state() }) return }
func main() { srv := &clonesrv_t{ port: 5556, kvmap: make(map[string]*kvmsg.Kvmsg), } // Set up our clone server sockets srv.snapshot, _ = zmq.NewSocket(zmq.ROUTER) srv.snapshot.Bind(fmt.Sprint("tcp://*:", srv.port)) srv.publisher, _ = zmq.NewSocket(zmq.PUB) srv.publisher.Bind(fmt.Sprint("tcp://*:", srv.port+1)) srv.collector, _ = zmq.NewSocket(zmq.PULL) srv.collector.Bind(fmt.Sprint("tcp://*:", srv.port+2)) // Register our handlers with reactor reactor := zmq.NewReactor() reactor.AddSocket(srv.snapshot, zmq.POLLIN, func(e zmq.State) error { return snapshots(srv) }) reactor.AddSocket(srv.collector, zmq.POLLIN, func(e zmq.State) error { return collector(srv) }) reactor.AddChannelTime(time.Tick(1000*time.Millisecond), 1, func(v interface{}) error { return flush_ttl(srv) }) log.Println(reactor.Run(100 * time.Millisecond)) // precision: .1 seconds }
// main entry point for data writer func main() { var err error var writerSocket *zmq4.Socket var eventSubSocket *zmq4.Socket fog.Info("program starts") if writerSocket, err = createWriterSocket(); err != nil { fog.Critical("createWriterSocket %s", err) } defer writerSocket.Close() fog.Info("binding writer socket to %s", dataWriterAddress) if err = writerSocket.Bind(dataWriterAddress); err != nil { fog.Critical("Bind(%s) %s", dataWriterAddress, err) } if eventSubSocket, err = createEventSubSocket(); err != nil { fog.Critical("createEventSubSocket %s", err) } defer eventSubSocket.Close() fog.Info("connecting event sub socket to %s", eventAggregatorPubAddress) if err = eventSubSocket.Connect(eventAggregatorPubAddress); err != nil { fog.Critical("Connect(%s) %s", eventAggregatorPubAddress, err) } messageChan := NewMessageHandler() reactor := zmq4.NewReactor() reactor.AddChannel(tools.NewSignalWatcher(), 1, tools.SigtermHandler) reactor.AddSocket(writerSocket, zmq4.POLLIN, NewWriterSocketHandler(writerSocket, messageChan)) reactor.AddSocket(eventSubSocket, zmq4.POLLIN, NewEventSubSocketHandler(eventSubSocket)) fog.Debug("starting reactor.Run") reactor.SetVerbose(true) err = reactor.Run(reactorPollingInterval) if err == tools.SigtermError { fog.Info("program terminates normally due to SIGTERM") } else if errno, ok := err.(syscall.Errno); ok { // we can get 'interrupted system call' if we get SIGTERM while // a socket is waiting on a read. That's not too bad. if errno == syscall.EINTR { fog.Warn("reactor.Run returns '%s' assuming SIGTERM", errno) } else { fog.Error("reactor.Run returns %T '%s'", errno, errno) } } else { fog.Error("reactor.Run returns %T %s", err, err) } }
// newNode creates a new node. func newNode(events chan *Event, cmds chan interface{}, replies chan interface{}) (n *node, err error) { n = &node{ reactor: zmq.NewReactor(), events: events, cmds: cmds, replies: replies, beaconPort: zreDiscoveryPort, peers: make(map[string]*peer), peerGroups: make(map[string]*group), ownGroups: make(map[string]*group), headers: make(map[string]string), terminated: make(chan interface{}), } n.beacon = beacon.New() n.inbox, err = zmq.NewSocket(zmq.ROUTER) if err != nil { return nil, err // Could not create new socket } err = n.inbox.SetIpv6(true) if err != nil { return nil, err } // Generate random uuid n.uuid = make([]byte, 16) io.ReadFull(crand.Reader, n.uuid) // Default name for node is first 6 characters of UUID: // the shorter string is more readable in logs n.name = fmt.Sprintf("%.6s", fmt.Sprintf("%X", n.uuid)) n.wg.Add(1) // We're going to wait until actor() is done return }
func TestMultipleContexts(t *testing.T) { chQuit := make(chan interface{}) chErr := make(chan error, 2) needQuit := false var sock1, sock2, serv1, serv2 *zmq.Socket var serv_ctx1, serv_ctx2, ctx1, ctx2 *zmq.Context var err error defer func() { if needQuit { chQuit <- true chQuit <- true <-chErr <-chErr } for _, s := range []*zmq.Socket{sock1, sock2, serv1, serv2} { if s != nil { s.SetLinger(0) s.Close() } } for _, c := range []*zmq.Context{serv_ctx1, serv_ctx2, ctx1, ctx2} { if c != nil { c.Term() } } }() addr1 := "tcp://127.0.0.1:9997" addr2 := "tcp://127.0.0.1:9998" serv_ctx1, err = zmq.NewContext() if err != nil { t.Fatal("NewContext:", err) } serv1, err = serv_ctx1.NewSocket(zmq.REP) if err != nil { t.Fatal("NewSocket:", err) } err = serv1.Bind(addr1) if err != nil { t.Fatal("Bind:", err) } serv_ctx2, err = zmq.NewContext() if err != nil { t.Fatal("NewContext:", err) } serv2, err = serv_ctx2.NewSocket(zmq.REP) if err != nil { t.Fatal("NewSocket:", err) } err = serv2.Bind(addr2) if err != nil { t.Fatal("Bind:", err) } new_service := func(sock *zmq.Socket, addr string) { socket_handler := func(state zmq.State) error { msg, err := sock.RecvMessage(0) if err != nil { return err } _, err = sock.SendMessage(addr, msg) return err } quit_handler := func(interface{}) error { return errors.New("quit") } reactor := zmq.NewReactor() reactor.AddSocket(sock, zmq.POLLIN, socket_handler) reactor.AddChannel(chQuit, 1, quit_handler) err = reactor.Run(100 * time.Millisecond) chErr <- err } go new_service(serv1, addr1) go new_service(serv2, addr2) needQuit = true time.Sleep(time.Second) // default context sock1, err = zmq.NewSocket(zmq.REQ) if err != nil { t.Fatal("NewSocket:", err) } sock2, err = zmq.NewSocket(zmq.REQ) if err != nil { t.Fatal("NewSocket:", err) } err = sock1.Connect(addr1) if err != nil { t.Fatal("sock1.Connect:", err) } err = sock2.Connect(addr2) if err != nil { t.Fatal("sock2.Connect:", err) } _, err = sock1.SendMessage(addr1) if err != nil { t.Fatal("sock1.SendMessage:", err) } _, err = sock2.SendMessage(addr2) if err != nil { t.Fatal("sock2.SendMessage:", err) } msg, err := sock1.RecvMessage(0) expected := []string{addr1, addr1} if err != nil || !arrayEqual(msg, expected) { t.Errorf("sock1.RecvMessage: expected %v %v, got %v %v", nil, expected, err, msg) } msg, err = sock2.RecvMessage(0) expected = []string{addr2, addr2} if err != nil || !arrayEqual(msg, expected) { t.Errorf("sock2.RecvMessage: expected %v %v, got %v %v", nil, expected, err, msg) } err = sock1.Close() sock1 = nil if err != nil { t.Fatal("sock1.Close:", err) } err = sock2.Close() sock2 = nil if err != nil { t.Fatal("sock2.Close:", err) } // non-default contexts ctx1, err = zmq.NewContext() if err != nil { t.Fatal("NewContext:", err) } ctx2, err = zmq.NewContext() if err != nil { t.Fatal("NewContext:", err) } sock1, err = ctx1.NewSocket(zmq.REQ) if err != nil { t.Fatal("ctx1.NewSocket:", err) } sock2, err = ctx2.NewSocket(zmq.REQ) if err != nil { t.Fatal("ctx2.NewSocket:", err) } err = sock1.Connect(addr1) if err != nil { t.Fatal("sock1.Connect:", err) } err = sock2.Connect(addr2) if err != nil { t.Fatal("sock2.Connect:", err) } _, err = sock1.SendMessage(addr1) if err != nil { t.Fatal("sock1.SendMessage:", err) } _, err = sock2.SendMessage(addr2) if err != nil { t.Fatal("sock2.SendMessage:", err) } msg, err = sock1.RecvMessage(0) expected = []string{addr1, addr1} if err != nil || !arrayEqual(msg, expected) { t.Errorf("sock1.RecvMessage: expected %v %v, got %v %v", nil, expected, err, msg) } msg, err = sock2.RecvMessage(0) expected = []string{addr2, addr2} if err != nil || !arrayEqual(msg, expected) { t.Errorf("sock2.RecvMessage: expected %v %v, got %v %v", nil, expected, err, msg) } err = sock1.Close() sock1 = nil if err != nil { t.Fatal("sock1.Close:", err) } err = sock2.Close() sock2 = nil if err != nil { t.Fatal("sock2.Close:", err) } err = ctx1.Term() ctx1 = nil if err != nil { t.Fatal("ctx1.Term", nil) } err = ctx2.Term() ctx1 = nil if err != nil { t.Fatal("ctx2.Term", nil) } needQuit = false for i := 0; i < 2; i++ { // close(chQuit) doesn't work because the reactor removes closed channels, instead of acting on them chQuit <- true err = <-chErr if err.Error() != "quit" { t.Errorf("Expected error value quit, got %v", err) } } }
func TestSecurityPlain(t *testing.T) { time.Sleep(100 * time.Millisecond) var handler, server, client *zmq.Socket defer func() { for _, s := range []*zmq.Socket{handler} { if s != nil { s.SetLinger(0) s.Close() } } }() handler, err := zmq.NewSocket(zmq.REP) if err != nil { t.Fatal("NewSocket:", err) } err = handler.Bind("inproc://zeromq.zap.01") if err != nil { t.Fatal("handler.Bind:", err) } doHandler := func(state zmq.State) error { msg, err := handler.RecvMessage(0) if err != nil { return err // Terminating } version := msg[0] sequence := msg[1] // domain := msg[2] // address := msg[3] identity := msg[4] mechanism := msg[5] username := msg[6] password := msg[7] if version != "1.0" { return errors.New("version != 1.0") } if mechanism != "PLAIN" { return errors.New("mechanism != PLAIN") } if identity != "IDENT" { return errors.New("identity != IDENT") } if username == "admin" && password == "password" { handler.SendMessage(version, sequence, "200", "OK", "anonymous", "") } else { handler.SendMessage(version, sequence, "400", "Invalid username or password", "", "") } return nil } doQuit := func(i interface{}) error { err := handler.Close() if err != nil { t.Error("handler.Close:", err) } return errors.New("Quit") } quit := make(chan interface{}) reactor := zmq.NewReactor() reactor.AddSocket(handler, zmq.POLLIN, doHandler) reactor.AddChannel(quit, 0, doQuit) go func() { reactor.Run(100 * time.Millisecond) quit <- true }() defer func() { quit <- true <-quit close(quit) }() // Server socket will accept connections server, err = zmq.NewSocket(zmq.DEALER) if err != nil { t.Fatal("NewSocket", err) } err = server.SetIdentity("IDENT") if err != nil { t.Fatal("server.SetIdentity:", err) } err = server.SetPlainServer(1) if err != nil { t.Fatal("server.SetPlainServer(1):", err) } err = server.Bind("tcp://127.0.0.1:9998") if err != nil { t.Fatal("server.Bind") } // Check PLAIN security with correct username/password client, err = zmq.NewSocket(zmq.DEALER) if err != nil { t.Fatal("NewSocket:", err) } err = client.SetPlainUsername("admin") if err != nil { t.Fatal("client.SetPlainUsername:"******"password") if err != nil { t.Fatal("client.SetPlainPassword:"******"tcp://127.0.0.1:9998") if err != nil { t.Fatal("client.Connect:", err) } msg, err := bounce(server, client) if err != nil { t.Error(msg, err) } err = client.Close() client = nil if err != nil { t.Fatal("client.Close:", err) } // Check PLAIN security with badly configured client (as_server) // This will be caught by the plain_server class, not passed to ZAP client, err = zmq.NewSocket(zmq.DEALER) if err != nil { t.Fatal("NewSocket:", err) } client.SetPlainServer(1) if err != nil { t.Fatal("client.SetPlainServer(1):", err) } err = client.Connect("tcp://127.0.0.1:9998") if err != nil { t.Fatal("client.Connect:", err) } err = client.SetRcvtimeo(time.Second) if err != nil { t.Fatal("client.SetRcvtimeo:", err) } err = server.SetRcvtimeo(time.Second) if err != nil { t.Fatal("server.SetRcvtimeo:", err) } _, err = bounce(server, client) if err == nil { t.Error("Expected failure, got success") } client.SetLinger(0) err = client.Close() client = nil if err != nil { t.Fatal("client.Close:", err) } err = server.Close() server = nil if err != nil { t.Fatal("server.Close:", err) } }
func TestSecurityNull(t *testing.T) { time.Sleep(100 * time.Millisecond) var handler, server, client *zmq.Socket defer func() { for _, s := range []*zmq.Socket{handler} { if s != nil { s.SetLinger(0) s.Close() } } }() handler, err := zmq.NewSocket(zmq.REP) if err != nil { t.Fatal("NewSocket:", err) } err = handler.Bind("inproc://zeromq.zap.01") if err != nil { t.Fatal("handler.Bind:", err) } doHandler := func(state zmq.State) error { msg, err := handler.RecvMessage(0) if err != nil { return err // Terminating } version := msg[0] sequence := msg[1] domain := msg[2] // address := msg[3] // identity := msg[4] mechanism := msg[5] if version != "1.0" { return errors.New("version != 1.0") } if mechanism != "NULL" { return errors.New("mechanism != NULL") } if domain == "TEST" { handler.SendMessage(version, sequence, "200", "OK", "anonymous", "") } else { handler.SendMessage(version, sequence, "400", "BAD DOMAIN", "", "") } return nil } doQuit := func(i interface{}) error { err := handler.Close() handler = nil if err != nil { t.Error("handler.Close:", err) } return errors.New("Quit") } quit := make(chan interface{}) reactor := zmq.NewReactor() reactor.AddSocket(handler, zmq.POLLIN, doHandler) reactor.AddChannel(quit, 0, doQuit) go func() { reactor.Run(100 * time.Millisecond) quit <- true }() defer func() { quit <- true <-quit close(quit) }() // We bounce between a binding server and a connecting client server, err = zmq.NewSocket(zmq.DEALER) if err != nil { t.Fatal("NewSocket:", err) } client, err = zmq.NewSocket(zmq.DEALER) if err != nil { t.Fatal("NewSocket:", err) } // We first test client/server with no ZAP domain // Libzmq does not call our ZAP handler, the connect must succeed err = server.Bind("tcp://127.0.0.1:9683") if err != nil { t.Fatal("server.Bind:", err) } err = client.Connect("tcp://127.0.0.1:9683") if err != nil { t.Fatal("client.Connect:", err) } msg, err := bounce(server, client) if err != nil { t.Error(msg, err) } server.Unbind("tcp://127.0.0.1:9683") client.Disconnect("tcp://127.0.0.1:9683") // Now define a ZAP domain for the server; this enables // authentication. We're using the wrong domain so this test // must fail. err = server.SetZapDomain("WRONG") if err != nil { t.Fatal("server.SetZapDomain:", err) } err = server.Bind("tcp://127.0.0.1:9687") if err != nil { t.Fatal("server.Bind:", err) } err = client.Connect("tcp://127.0.0.1:9687") if err != nil { t.Fatal("client.Connect:", err) } err = client.SetRcvtimeo(time.Second) if err != nil { t.Fatal("client.SetRcvtimeo:", err) } err = server.SetRcvtimeo(time.Second) if err != nil { t.Fatal("server.SetRcvtimeo:", err) } _, err = bounce(server, client) if err == nil { t.Error("Expected failure, got success") } server.Unbind("tcp://127.0.0.1:9687") client.Disconnect("tcp://127.0.0.1:9687") // Now use the right domain, the test must pass err = server.SetZapDomain("TEST") if err != nil { t.Fatal("server.SetZapDomain:", err) } err = server.Bind("tcp://127.0.0.1:9688") if err != nil { t.Fatal("server.Bind:", err) } err = client.Connect("tcp://127.0.0.1:9688") if err != nil { t.Fatal("client.Connect:", err) } msg, err = bounce(server, client) if err != nil { t.Error(msg, err) } server.Unbind("tcp://127.0.0.1:9688") client.Disconnect("tcp://127.0.0.1:9688") err = client.Close() client = nil if err != nil { t.Error("client.Close:", err) } err = server.Close() server = nil if err != nil { t.Error("server.Close:", err) } }
func TestSecurityCurve(t *testing.T) { time.Sleep(100 * time.Millisecond) var handler, server, client *zmq.Socket defer func() { for _, s := range []*zmq.Socket{handler} { if s != nil { s.SetLinger(0) s.Close() } } }() if _, minor, _ := zmq.Version(); minor >= 1 && !zmq.HasCurve() { t.Skip("Curve not available") } // Generate new keypairs for this test client_public, client_secret, err := zmq.NewCurveKeypair() if err != nil { t.Fatal("NewCurveKeypair:", err) } server_public, server_secret, err := zmq.NewCurveKeypair() if err != nil { t.Fatal("NewCurveKeypair:", err) } handler, err = zmq.NewSocket(zmq.REP) if err != nil { t.Fatal("NewSocket:", err) } err = handler.Bind("inproc://zeromq.zap.01") if err != nil { t.Fatal("handler.Bind:", err) } doHandler := func(state zmq.State) error { msg, err := handler.RecvMessage(0) if err != nil { return err // Terminating } version := msg[0] sequence := msg[1] // domain := msg[2] // address := msg[3] identity := msg[4] mechanism := msg[5] client_key := msg[6] client_key_text := zmq.Z85encode(client_key) if version != "1.0" { return errors.New("version != 1.0") } if mechanism != "CURVE" { return errors.New("mechanism != CURVE") } if identity != "IDENT" { return errors.New("identity != IDENT") } if client_key_text == client_public { handler.SendMessage(version, sequence, "200", "OK", "anonymous", "") } else { handler.SendMessage(version, sequence, "400", "Invalid client public key", "", "") } return nil } doQuit := func(i interface{}) error { err := handler.Close() handler = nil if err != nil { t.Error("handler.Close:", err) } return errors.New("Quit") } quit := make(chan interface{}) reactor := zmq.NewReactor() reactor.AddSocket(handler, zmq.POLLIN, doHandler) reactor.AddChannel(quit, 0, doQuit) go func() { reactor.Run(100 * time.Millisecond) quit <- true }() defer func() { quit <- true <-quit close(quit) }() // Server socket will accept connections server, err = zmq.NewSocket(zmq.DEALER) if err != nil { t.Fatal("NewSocket:", err) } err = server.SetCurveServer(1) if err != nil { t.Fatal("server.SetCurveServer(1):", err) } err = server.SetCurveSecretkey(server_secret) if err != nil { t.Fatal("server.SetCurveSecretkey:", err) } err = server.SetIdentity("IDENT") if err != nil { t.Fatal("server.SetIdentity:", err) } server.Bind("tcp://127.0.0.1:9998") if err != nil { t.Fatal("server.Bind:", err) } err = server.SetRcvtimeo(time.Second) if err != nil { t.Fatal("server.SetRcvtimeo:", err) } // Check CURVE security with valid credentials client, err = zmq.NewSocket(zmq.DEALER) if err != nil { t.Fatal("NewSocket:", err) } err = client.SetCurveServerkey(server_public) if err != nil { t.Fatal("client.SetCurveServerkey:", err) } err = client.SetCurvePublickey(client_public) if err != nil { t.Fatal("client.SetCurvePublickey:", err) } err = client.SetCurveSecretkey(client_secret) if err != nil { t.Fatal("client.SetCurveSecretkey:", err) } err = client.Connect("tcp://127.0.0.1:9998") if err != nil { t.Fatal("client.Connect:", err) } msg, err := bounce(server, client) if err != nil { t.Error(msg, err) } err = client.Close() client = nil if err != nil { t.Fatal("client.Close:", err) } time.Sleep(100 * time.Millisecond) // Check CURVE security with a garbage server key // This will be caught by the curve_server class, not passed to ZAP garbage_key := "0000111122223333444455556666777788889999" client, err = zmq.NewSocket(zmq.DEALER) if err != nil { t.Fatal("NewSocket:", err) } err = client.SetCurveServerkey(garbage_key) if err != nil { t.Fatal("client.SetCurveServerkey:", err) } err = client.SetCurvePublickey(client_public) if err != nil { t.Fatal("client.SetCurvePublickey:", err) } err = client.SetCurveSecretkey(client_secret) if err != nil { t.Fatal("client.SetCurveSecretkey:", err) } err = client.Connect("tcp://127.0.0.1:9998") if err != nil { t.Fatal("client.Connect:", err) } err = client.SetRcvtimeo(time.Second) if err != nil { t.Fatal("client.SetRcvtimeo:", err) } _, err = bounce(server, client) if err == nil { t.Error("Expected failure, got success") } client.SetLinger(0) err = client.Close() client = nil if err != nil { t.Fatal("client.Close:", err) } time.Sleep(100 * time.Millisecond) // Check CURVE security with a garbage client secret key // This will be caught by the curve_server class, not passed to ZAP client, err = zmq.NewSocket(zmq.DEALER) if err != nil { t.Fatal("NewSocket:", err) } err = client.SetCurveServerkey(server_public) if err != nil { t.Fatal("client.SetCurveServerkey:", err) } err = client.SetCurvePublickey(garbage_key) if err != nil { t.Fatal("client.SetCurvePublickey:", err) } err = client.SetCurveSecretkey(client_secret) if err != nil { t.Fatal("client.SetCurveSecretkey:", err) } err = client.Connect("tcp://127.0.0.1:9998") if err != nil { t.Fatal("client.Connect:", err) } err = client.SetRcvtimeo(time.Second) if err != nil { t.Fatal("client.SetRcvtimeo:", err) } _, err = bounce(server, client) if err == nil { t.Error("Expected failure, got success") } client.SetLinger(0) err = client.Close() client = nil if err != nil { t.Fatal("client.Close:", err) } time.Sleep(100 * time.Millisecond) // Check CURVE security with a garbage client secret key // This will be caught by the curve_server class, not passed to ZAP client, err = zmq.NewSocket(zmq.DEALER) if err != nil { t.Fatal("NewSocket:", err) } err = client.SetCurveServerkey(server_public) if err != nil { t.Fatal("client.SetCurveServerkey:", err) } err = client.SetCurvePublickey(client_public) if err != nil { t.Fatal("client.SetCurvePublickey:", err) } err = client.SetCurveSecretkey(garbage_key) if err != nil { t.Fatal("client.SetCurveSecretkey:", err) } err = client.Connect("tcp://127.0.0.1:9998") if err != nil { t.Fatal("client.Connect:", err) } err = client.SetRcvtimeo(time.Second) if err != nil { t.Fatal("client.SetRcvtimeo:", err) } _, err = bounce(server, client) if err == nil { t.Error("Expected failure, got success") } client.SetLinger(0) err = client.Close() client = nil if err != nil { t.Fatal("client.Close:", err) } time.Sleep(100 * time.Millisecond) // Check CURVE security with bogus client credentials // This must be caught by the ZAP handler bogus_public, bogus_secret, _ := zmq.NewCurveKeypair() client, err = zmq.NewSocket(zmq.DEALER) if err != nil { t.Fatal("NewSocket:", err) } err = client.SetCurveServerkey(server_public) if err != nil { t.Fatal("client.SetCurveServerkey:", err) } err = client.SetCurvePublickey(bogus_public) if err != nil { t.Fatal("client.SetCurvePublickey:", err) } err = client.SetCurveSecretkey(bogus_secret) if err != nil { t.Fatal("client.SetCurveSecretkey:", err) } err = client.Connect("tcp://127.0.0.1:9998") if err != nil { t.Fatal("client.Connect:", err) } err = client.SetRcvtimeo(time.Second) if err != nil { t.Fatal("client.SetRcvtimeo:", err) } _, err = bounce(server, client) if err == nil { t.Error("Expected failure, got success") } client.SetLinger(0) err = client.Close() client = nil if err != nil { t.Fatal("client.Close:", err) } // Shutdown err = server.Close() server = nil if err != nil { t.Error("server.Close:", err) } }
func (client *Client) send(ctx context.Context, call *Call) error { if client.shutdown || client.closing { return ErrShutdown } // Every call gets its own req socket sock, err := client.ctx.NewSocket(zmq.REQ) if err != nil { return err } defer sock.Close() // Connect it to the router if err := sock.Connect(RouterURL); err != nil { return err } // Marshal the outgoing message msgBytes, err := proto.Marshal(call.Req) if err != nil { return err } // Envelope the message reqID := uuid.NewV4() envelope := &Request{ UUID: reqID.Bytes(), Path: proto.String(fmt.Sprintf("zrpc://%s/%s", call.Service, util.GetMessageName(call.Req))), Payload: msgBytes, } // If request has a timeout, send it in the request envelope d, ok := ctx.Deadline() if ok { envelope.Expires = proto.Int64(d.Unix()) } // Marshal the outgoing envelope envBytes, err := proto.Marshal(envelope) if err != nil { return err } // Send it if _, err := sock.SendBytes(envBytes, 0); err != nil { return err } handleResponse := func(state zmq.State) error { respBytes, err := sock.RecvBytes(0) if err != nil { return err } // Unmarshal the response envelope resp := &Response{} if err := proto.Unmarshal(respBytes, resp); err != nil { return err } // Make sure the same message ID was received respID, err := uuid.FromBytes(resp.UUID) if err != nil || !uuid.Equal(reqID, respID) { glog.Errorf("Mismatching message IDs, sent '%s', got '%s'", reqID, respID) return ErrMessageMismatch } // Check if there is an error if resp.Error != nil { return NewClientError(resp.Error.GetMessage(), int(resp.GetStatusCode())) } // Decode the actual message (if exists and wanted) if call.Resp != nil && len(resp.Payload) > 0 { if err := proto.Unmarshal(resp.Payload, call.Resp); err != nil { return err } } // This is insane, but the reactor runs until an error is returned... return errDone } // Use a reactor to be able to utilize the calls cancelc reactor := zmq.NewReactor() reactor.AddSocket(sock, zmq.POLLIN, handleResponse) reactor.AddChannel(call.cancelc, 1, func(interface{}) error { return ErrCancel }) // Poll for a short interval to be able to return to the channel handling if err := reactor.Run(time.Millisecond * 50); err != errDone { return err } return nil }
func Example_multiple_contexts() { chQuit := make(chan interface{}) chReactor := make(chan bool) addr1 := "tcp://127.0.0.1:9997" addr2 := "tcp://127.0.0.1:9998" serv_ctx1, err := zmq.NewContext() if checkErr(err) { return } serv1, err := serv_ctx1.NewSocket(zmq.REP) if checkErr(err) { return } err = serv1.Bind(addr1) if checkErr(err) { return } defer func() { serv1.Close() serv_ctx1.Term() }() serv_ctx2, err := zmq.NewContext() if checkErr(err) { return } serv2, err := serv_ctx2.NewSocket(zmq.REP) if checkErr(err) { return } err = serv2.Bind(addr2) if checkErr(err) { return } defer func() { serv2.Close() serv_ctx2.Term() }() new_service := func(sock *zmq.Socket, addr string) { socket_handler := func(state zmq.State) error { msg, err := sock.RecvMessage(0) if checkErr(err) { return err } _, err = sock.SendMessage(addr, msg) if checkErr(err) { return err } return nil } quit_handler := func(interface{}) error { return errors.New("quit") } defer func() { chReactor <- true }() reactor := zmq.NewReactor() reactor.AddSocket(sock, zmq.POLLIN, socket_handler) reactor.AddChannel(chQuit, 1, quit_handler) err = reactor.Run(100 * time.Millisecond) fmt.Println(err) } go new_service(serv1, addr1) go new_service(serv2, addr2) time.Sleep(time.Second) // default context sock1, err := zmq.NewSocket(zmq.REQ) if checkErr(err) { return } sock2, err := zmq.NewSocket(zmq.REQ) if checkErr(err) { return } err = sock1.Connect(addr1) if checkErr(err) { return } err = sock2.Connect(addr2) if checkErr(err) { return } _, err = sock1.SendMessage(addr1) if checkErr(err) { return } _, err = sock2.SendMessage(addr2) if checkErr(err) { return } msg, err := sock1.RecvMessage(0) fmt.Println(err, msg) msg, err = sock2.RecvMessage(0) fmt.Println(err, msg) err = sock1.Close() if checkErr(err) { return } err = sock2.Close() if checkErr(err) { return } // non-default contexts ctx1, err := zmq.NewContext() if checkErr(err) { return } ctx2, err := zmq.NewContext() if checkErr(err) { return } sock1, err = ctx1.NewSocket(zmq.REQ) if checkErr(err) { return } sock2, err = ctx2.NewSocket(zmq.REQ) if checkErr(err) { return } err = sock1.Connect(addr1) if checkErr(err) { return } err = sock2.Connect(addr2) if checkErr(err) { return } _, err = sock1.SendMessage(addr1) if checkErr(err) { return } _, err = sock2.SendMessage(addr2) if checkErr(err) { return } msg, err = sock1.RecvMessage(0) fmt.Println(err, msg) msg, err = sock2.RecvMessage(0) fmt.Println(err, msg) err = sock1.Close() if checkErr(err) { return } err = sock2.Close() if checkErr(err) { return } err = ctx1.Term() if checkErr(err) { return } err = ctx2.Term() if checkErr(err) { return } // close(chQuit) doesn't work because the reactor removes closed channels, instead of acting on them chQuit <- true <-chReactor chQuit <- true <-chReactor fmt.Println("Done") // Output: // <nil> [tcp://127.0.0.1:9997 tcp://127.0.0.1:9997] // <nil> [tcp://127.0.0.1:9998 tcp://127.0.0.1:9998] // <nil> [tcp://127.0.0.1:9997 tcp://127.0.0.1:9997] // <nil> [tcp://127.0.0.1:9998 tcp://127.0.0.1:9998] // quit // quit // Done }
func Example_test_security_plain() { time.Sleep(100 * time.Millisecond) handler, err := zmq.NewSocket(zmq.REP) if checkErr(err) { return } err = handler.Bind("inproc://zeromq.zap.01") if checkErr(err) { return } doHandler := func(state zmq.State) error { msg, err := handler.RecvMessage(0) if err != nil { return err // Terminating } version := msg[0] sequence := msg[1] // domain := msg[2] // address := msg[3] identity := msg[4] mechanism := msg[5] username := msg[6] password := msg[7] if version != "1.0" { return errors.New("version != 1.0") } if mechanism != "PLAIN" { return errors.New("mechanism != PLAIN") } if identity != "IDENT" { return errors.New("identity != IDENT") } if username == "admin" && password == "password" { handler.SendMessage(version, sequence, "200", "OK", "anonymous", "") } else { handler.SendMessage(version, sequence, "400", "Invalid username or password", "", "") } return nil } doQuit := func(i interface{}) error { err := handler.Close() checkErr(err) fmt.Println("Handler closed") return errors.New("Quit") } quit := make(chan interface{}) reactor := zmq.NewReactor() reactor.AddSocket(handler, zmq.POLLIN, doHandler) reactor.AddChannel(quit, 0, doQuit) go func() { reactor.Run(100 * time.Millisecond) fmt.Println("Reactor finished") quit <- true }() defer func() { quit <- true <-quit close(quit) }() // Server socket will accept connections server, err := zmq.NewSocket(zmq.DEALER) if checkErr(err) { return } err = server.SetIdentity("IDENT") if checkErr(err) { return } err = server.SetPlainServer(1) if checkErr(err) { return } err = server.Bind("tcp://127.0.0.1:9998") if checkErr(err) { return } // Check PLAIN security with correct username/password client, err := zmq.NewSocket(zmq.DEALER) if checkErr(err) { return } err = client.SetPlainUsername("admin") if checkErr(err) { return } err = client.SetPlainPassword("password") if checkErr(err) { return } err = client.Connect("tcp://127.0.0.1:9998") if checkErr(err) { return } bounce(server, client, false) err = client.Close() if checkErr(err) { return } // Check PLAIN security with badly configured client (as_server) // This will be caught by the plain_server class, not passed to ZAP client, err = zmq.NewSocket(zmq.DEALER) if checkErr(err) { return } client.SetPlainServer(1) if checkErr(err) { return } err = client.Connect("tcp://127.0.0.1:9998") if checkErr(err) { return } err = client.SetRcvtimeo(time.Second) if checkErr(err) { return } err = server.SetRcvtimeo(time.Second) if checkErr(err) { return } bounce(server, client, true) client.SetLinger(0) err = client.Close() if checkErr(err) { return } err = server.Close() checkErr(err) fmt.Println("Done") // Output: // 5 error // Done // Handler closed // Reactor finished }
func Example_test_security_null() { time.Sleep(100 * time.Millisecond) handler, err := zmq.NewSocket(zmq.REP) if checkErr(err) { return } err = handler.Bind("inproc://zeromq.zap.01") if checkErr(err) { return } doHandler := func(state zmq.State) error { msg, err := handler.RecvMessage(0) if err != nil { return err // Terminating } version := msg[0] sequence := msg[1] domain := msg[2] // address := msg[3] // identity := msg[4] mechanism := msg[5] if version != "1.0" { return errors.New("version != 1.0") } if mechanism != "NULL" { return errors.New("mechanism != NULL") } if domain == "TEST" { handler.SendMessage(version, sequence, "200", "OK", "anonymous", "") } else { handler.SendMessage(version, sequence, "400", "BAD DOMAIN", "", "") } return nil } doQuit := func(i interface{}) error { err := handler.Close() checkErr(err) fmt.Println("Handler closed") return errors.New("Quit") } quit := make(chan interface{}) reactor := zmq.NewReactor() reactor.AddSocket(handler, zmq.POLLIN, doHandler) reactor.AddChannel(quit, 0, doQuit) go func() { reactor.Run(100 * time.Millisecond) fmt.Println("Reactor finished") quit <- true }() defer func() { quit <- true <-quit close(quit) }() // We bounce between a binding server and a connecting client server, err := zmq.NewSocket(zmq.DEALER) if checkErr(err) { return } client, err := zmq.NewSocket(zmq.DEALER) if checkErr(err) { return } // We first test client/server with no ZAP domain // Libzmq does not call our ZAP handler, the connect must succeed err = server.Bind("tcp://127.0.0.1:9683") if checkErr(err) { return } err = client.Connect("tcp://127.0.0.1:9683") if checkErr(err) { return } bounce(server, client, false) server.Unbind("tcp://127.0.0.1:9683") client.Disconnect("tcp://127.0.0.1:9683") // Now define a ZAP domain for the server; this enables // authentication. We're using the wrong domain so this test // must fail. err = server.SetZapDomain("WRONG") if checkErr(err) { return } err = server.Bind("tcp://127.0.0.1:9687") if checkErr(err) { return } err = client.Connect("tcp://127.0.0.1:9687") if checkErr(err) { return } err = client.SetRcvtimeo(time.Second) if checkErr(err) { return } err = server.SetRcvtimeo(time.Second) if checkErr(err) { return } bounce(server, client, true) server.Unbind("tcp://127.0.0.1:9687") client.Disconnect("tcp://127.0.0.1:9687") // Now use the right domain, the test must pass err = server.SetZapDomain("TEST") if checkErr(err) { return } err = server.Bind("tcp://127.0.0.1:9688") if checkErr(err) { return } err = client.Connect("tcp://127.0.0.1:9688") if checkErr(err) { return } bounce(server, client, false) server.Unbind("tcp://127.0.0.1:9688") client.Disconnect("tcp://127.0.0.1:9688") err = client.Close() checkErr(err) err = server.Close() checkErr(err) fmt.Println("Done") // Output: // 5 error // Done // Handler closed // Reactor finished }
func Example_test_security_curve() { time.Sleep(100 * time.Millisecond) // Generate new keypairs for this test client_public, client_secret, err := zmq.NewCurveKeypair() if checkErr(err) { return } server_public, server_secret, err := zmq.NewCurveKeypair() if checkErr(err) { return } handler, err := zmq.NewSocket(zmq.REP) if checkErr(err) { return } err = handler.Bind("inproc://zeromq.zap.01") if checkErr(err) { return } doHandler := func(state zmq.State) error { msg, err := handler.RecvMessage(0) if err != nil { return err // Terminating } version := msg[0] sequence := msg[1] // domain := msg[2] // address := msg[3] identity := msg[4] mechanism := msg[5] client_key := msg[6] client_key_text := zmq.Z85encode(client_key) if version != "1.0" { return errors.New("version != 1.0") } if mechanism != "CURVE" { return errors.New("mechanism != CURVE") } if identity != "IDENT" { return errors.New("identity != IDENT") } if client_key_text == client_public { handler.SendMessage(version, sequence, "200", "OK", "anonymous", "") } else { handler.SendMessage(version, sequence, "400", "Invalid client public key", "", "") } return nil } doQuit := func(i interface{}) error { err := handler.Close() checkErr(err) fmt.Println("Handler closed") return errors.New("Quit") } quit := make(chan interface{}) reactor := zmq.NewReactor() reactor.AddSocket(handler, zmq.POLLIN, doHandler) reactor.AddChannel(quit, 0, doQuit) go func() { reactor.Run(100 * time.Millisecond) fmt.Println("Reactor finished") quit <- true }() defer func() { quit <- true <-quit close(quit) }() // Server socket will accept connections server, err := zmq.NewSocket(zmq.DEALER) if checkErr(err) { return } err = server.SetCurveServer(1) if checkErr(err) { return } err = server.SetCurveSecretkey(server_secret) if checkErr(err) { return } err = server.SetIdentity("IDENT") if checkErr(err) { return } server.Bind("tcp://127.0.0.1:9998") if checkErr(err) { return } err = server.SetRcvtimeo(time.Second) if checkErr(err) { return } // Check CURVE security with valid credentials client, err := zmq.NewSocket(zmq.DEALER) if checkErr(err) { return } err = client.SetCurveServerkey(server_public) if checkErr(err) { return } err = client.SetCurvePublickey(client_public) if checkErr(err) { return } err = client.SetCurveSecretkey(client_secret) if checkErr(err) { return } err = client.Connect("tcp://127.0.0.1:9998") if checkErr(err) { return } bounce(server, client, false) err = client.Close() if checkErr(err) { return } time.Sleep(100 * time.Millisecond) // Check CURVE security with a garbage server key // This will be caught by the curve_server class, not passed to ZAP garbage_key := "0000111122223333444455556666777788889999" client, err = zmq.NewSocket(zmq.DEALER) if checkErr(err) { return } err = client.SetCurveServerkey(garbage_key) if checkErr(err) { return } err = client.SetCurvePublickey(client_public) if checkErr(err) { return } err = client.SetCurveSecretkey(client_secret) if checkErr(err) { return } err = client.Connect("tcp://127.0.0.1:9998") if checkErr(err) { return } err = client.SetRcvtimeo(time.Second) if checkErr(err) { return } bounce(server, client, true) client.SetLinger(0) err = client.Close() if checkErr(err) { return } time.Sleep(100 * time.Millisecond) // Check CURVE security with a garbage client secret key // This will be caught by the curve_server class, not passed to ZAP client, err = zmq.NewSocket(zmq.DEALER) if checkErr(err) { return } err = client.SetCurveServerkey(server_public) if checkErr(err) { return } err = client.SetCurvePublickey(garbage_key) if checkErr(err) { return } err = client.SetCurveSecretkey(client_secret) if checkErr(err) { return } err = client.Connect("tcp://127.0.0.1:9998") if checkErr(err) { return } err = client.SetRcvtimeo(time.Second) if checkErr(err) { return } bounce(server, client, true) client.SetLinger(0) err = client.Close() if checkErr(err) { return } time.Sleep(100 * time.Millisecond) // Check CURVE security with a garbage client secret key // This will be caught by the curve_server class, not passed to ZAP client, err = zmq.NewSocket(zmq.DEALER) if checkErr(err) { return } err = client.SetCurveServerkey(server_public) if checkErr(err) { return } err = client.SetCurvePublickey(client_public) if checkErr(err) { return } err = client.SetCurveSecretkey(garbage_key) if checkErr(err) { return } err = client.Connect("tcp://127.0.0.1:9998") if checkErr(err) { return } err = client.SetRcvtimeo(time.Second) if checkErr(err) { return } bounce(server, client, true) client.SetLinger(0) err = client.Close() if checkErr(err) { return } time.Sleep(100 * time.Millisecond) // Check CURVE security with bogus client credentials // This must be caught by the ZAP handler bogus_public, bogus_secret, _ := zmq.NewCurveKeypair() client, err = zmq.NewSocket(zmq.DEALER) if checkErr(err) { return } err = client.SetCurveServerkey(server_public) if checkErr(err) { return } err = client.SetCurvePublickey(bogus_public) if checkErr(err) { return } err = client.SetCurveSecretkey(bogus_secret) if checkErr(err) { return } err = client.Connect("tcp://127.0.0.1:9998") if checkErr(err) { return } err = client.SetRcvtimeo(time.Second) if checkErr(err) { return } bounce(server, client, true) client.SetLinger(0) err = client.Close() if checkErr(err) { return } // Shutdown err = server.Close() checkErr(err) fmt.Println("Done") // Output: // 5 error // 5 error // 5 error // 5 error // Done // Handler closed // Reactor finished }