forked from hush/lightwalletd
mdr0id
5 years ago
21 changed files with 1 additions and 4472 deletions
@ -1,25 +0,0 @@ |
|||||
Copyright (c) 2013-2014, Peter Kleiweg |
|
||||
All rights reserved. |
|
||||
|
|
||||
Redistribution and use in source and binary forms, with or without |
|
||||
modification, are permitted provided that the following conditions are |
|
||||
met: |
|
||||
|
|
||||
1. Redistributions of source code must retain the above copyright |
|
||||
notice, this list of conditions and the following disclaimer. |
|
||||
|
|
||||
2. Redistributions in binary form must reproduce the above copyright |
|
||||
notice, this list of conditions and the following disclaimer in the |
|
||||
documentation and/or other materials provided with the distribution. |
|
||||
|
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS |
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED |
|
||||
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
@ -1,75 +0,0 @@ |
|||||
A Go interface to [ZeroMQ](http://www.zeromq.org/) version 4. |
|
||||
|
|
||||
[![Go Report Card](https://goreportcard.com/badge/github.com/pebbe/zmq4)](https://goreportcard.com/report/github.com/pebbe/zmq4) |
|
||||
[![GoDoc](https://godoc.org/github.com/pebbe/zmq4?status.svg)](https://godoc.org/github.com/pebbe/zmq4) |
|
||||
|
|
||||
This requires ZeroMQ version 4.0.1 or above. To use CURVE security in |
|
||||
versions prior to 4.2, ZeroMQ must be installed with |
|
||||
[libsodium](https://github.com/jedisct1/libsodium) enabled. |
|
||||
|
|
||||
Partial support for ZeroMQ 4.2 DRAFT is available in the alternate |
|
||||
version of zmq4 `draft`. The API pertaining to this is subject to |
|
||||
change. To use this: |
|
||||
|
|
||||
import ( |
|
||||
zmq "github.com/pebbe/zmq4/draft" |
|
||||
) |
|
||||
|
|
||||
For ZeroMQ version 3, see: http://github.com/pebbe/zmq3 |
|
||||
|
|
||||
For ZeroMQ version 2, see: http://github.com/pebbe/zmq2 |
|
||||
|
|
||||
Including all examples of [ØMQ - The Guide](http://zguide.zeromq.org/page:all). |
|
||||
|
|
||||
Keywords: zmq, zeromq, 0mq, networks, distributed computing, message passing, fanout, pubsub, pipeline, request-reply |
|
||||
|
|
||||
### See also |
|
||||
|
|
||||
* [Mangos](https://github.com/go-mangos/mangos) — An implementation in pure Go of the SP ("Scalable Protocols") protocols |
|
||||
* [go-nanomsg](https://github.com/op/go-nanomsg) — Language bindings for nanomsg in Go |
|
||||
* [goczmq](https://github.com/zeromq/goczmq) — A Go interface to CZMQ |
|
||||
|
|
||||
## Install |
|
||||
|
|
||||
go get github.com/pebbe/zmq4 |
|
||||
|
|
||||
## Docs |
|
||||
|
|
||||
* [package help](http://godoc.org/github.com/pebbe/zmq4) |
|
||||
* [wiki](https://github.com/pebbe/zmq4/wiki) |
|
||||
|
|
||||
## API change |
|
||||
|
|
||||
There has been an API change in commit |
|
||||
0bc5ab465849847b0556295d9a2023295c4d169e of 2014-06-27, 10:17:55 UTC |
|
||||
in the functions `AuthAllow` and `AuthDeny`. |
|
||||
|
|
||||
Old: |
|
||||
|
|
||||
func AuthAllow(addresses ...string) |
|
||||
func AuthDeny(addresses ...string) |
|
||||
|
|
||||
New: |
|
||||
|
|
||||
func AuthAllow(domain string, addresses ...string) |
|
||||
func AuthDeny(domain string, addresses ...string) |
|
||||
|
|
||||
If `domain` can be parsed as an IP address, it will be interpreted as |
|
||||
such, and it and all remaining addresses are added to all domains. |
|
||||
|
|
||||
So this should still work as before: |
|
||||
|
|
||||
zmq.AuthAllow("127.0.0.1", "123.123.123.123") |
|
||||
|
|
||||
But this won't compile: |
|
||||
|
|
||||
a := []string{"127.0.0.1", "123.123.123.123"} |
|
||||
zmq.AuthAllow(a...) |
|
||||
|
|
||||
And needs to be rewritten as: |
|
||||
|
|
||||
a := []string{"127.0.0.1", "123.123.123.123"} |
|
||||
zmq.AuthAllow("*", a...) |
|
||||
|
|
||||
Furthermore, an address can now be a single IP address, as well as an IP |
|
||||
address and mask in CIDR notation, e.g. "123.123.123.0/24". |
|
@ -1,645 +0,0 @@ |
|||||
/* |
|
||||
|
|
||||
This file implements functionality very similar to that of the xauth module in czmq. |
|
||||
|
|
||||
Notable differences in here: |
|
||||
|
|
||||
- domains are supported |
|
||||
- domains are used in AuthAllow and AuthDeny too |
|
||||
- usernames/passwords are read from memory, not from file |
|
||||
- public keys are read from memory, not from file |
|
||||
- an address can be a single IP address, or an IP address and mask in CIDR notation |
|
||||
- additional functions for configuring server or client socket with a single command |
|
||||
|
|
||||
*/ |
|
||||
|
|
||||
package zmq4 |
|
||||
|
|
||||
/* |
|
||||
#include <zmq.h> |
|
||||
#include <stdlib.h> |
|
||||
|
|
||||
#if ZMQ_VERSION_MINOR < 2 |
|
||||
// Version < 4.2.x
|
|
||||
|
|
||||
int zmq_curve_public (char *z85_public_key, const char *z85_secret_key) { return 0; } |
|
||||
|
|
||||
#endif // Version < 4.2.x
|
|
||||
*/ |
|
||||
import "C" |
|
||||
|
|
||||
import ( |
|
||||
"errors" |
|
||||
"log" |
|
||||
"net" |
|
||||
"strings" |
|
||||
"unsafe" |
|
||||
) |
|
||||
|
|
||||
const CURVE_ALLOW_ANY = "*" |
|
||||
|
|
||||
var ( |
|
||||
auth_handler *Socket |
|
||||
auth_quit *Socket |
|
||||
|
|
||||
auth_init = false |
|
||||
auth_verbose = false |
|
||||
|
|
||||
auth_allow = make(map[string]map[string]bool) |
|
||||
auth_deny = make(map[string]map[string]bool) |
|
||||
auth_allow_net = make(map[string][]*net.IPNet) |
|
||||
auth_deny_net = make(map[string][]*net.IPNet) |
|
||||
|
|
||||
auth_users = make(map[string]map[string]string) |
|
||||
|
|
||||
auth_pubkeys = make(map[string]map[string]bool) |
|
||||
|
|
||||
auth_meta_handler = auth_meta_handler_default |
|
||||
) |
|
||||
|
|
||||
func auth_meta_handler_default(version, request_id, domain, address, identity, mechanism string, credentials ...string) (metadata map[string]string) { |
|
||||
return map[string]string{} |
|
||||
} |
|
||||
|
|
||||
func auth_isIP(addr string) bool { |
|
||||
if net.ParseIP(addr) != nil { |
|
||||
return true |
|
||||
} |
|
||||
if _, _, err := net.ParseCIDR(addr); err == nil { |
|
||||
return true |
|
||||
} |
|
||||
return false |
|
||||
} |
|
||||
|
|
||||
func auth_is_allowed(domain, address string) bool { |
|
||||
for _, d := range []string{domain, "*"} { |
|
||||
if a, ok := auth_allow[d]; ok { |
|
||||
if a[address] { |
|
||||
return true |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
addr := net.ParseIP(address) |
|
||||
if addr != nil { |
|
||||
for _, d := range []string{domain, "*"} { |
|
||||
if a, ok := auth_allow_net[d]; ok { |
|
||||
for _, m := range a { |
|
||||
if m.Contains(addr) { |
|
||||
return true |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
return false |
|
||||
} |
|
||||
|
|
||||
func auth_is_denied(domain, address string) bool { |
|
||||
for _, d := range []string{domain, "*"} { |
|
||||
if a, ok := auth_deny[d]; ok { |
|
||||
if a[address] { |
|
||||
return true |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
addr := net.ParseIP(address) |
|
||||
if addr != nil { |
|
||||
for _, d := range []string{domain, "*"} { |
|
||||
if a, ok := auth_deny_net[d]; ok { |
|
||||
for _, m := range a { |
|
||||
if m.Contains(addr) { |
|
||||
return true |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
return false |
|
||||
} |
|
||||
|
|
||||
func auth_has_allow(domain string) bool { |
|
||||
for _, d := range []string{domain, "*"} { |
|
||||
if a, ok := auth_allow[d]; ok { |
|
||||
if len(a) > 0 || len(auth_allow_net[d]) > 0 { |
|
||||
return true |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
return false |
|
||||
} |
|
||||
|
|
||||
func auth_has_deny(domain string) bool { |
|
||||
for _, d := range []string{domain, "*"} { |
|
||||
if a, ok := auth_deny[d]; ok { |
|
||||
if len(a) > 0 || len(auth_deny_net[d]) > 0 { |
|
||||
return true |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
return false |
|
||||
} |
|
||||
|
|
||||
func auth_do_handler() { |
|
||||
for { |
|
||||
|
|
||||
msg, err := auth_handler.RecvMessage(0) |
|
||||
if err != nil { |
|
||||
if auth_verbose { |
|
||||
log.Println("AUTH: Quitting:", err) |
|
||||
} |
|
||||
break |
|
||||
} |
|
||||
|
|
||||
if msg[0] == "QUIT" { |
|
||||
if auth_verbose { |
|
||||
log.Println("AUTH: Quitting: received QUIT message") |
|
||||
} |
|
||||
_, err := auth_handler.SendMessage("QUIT") |
|
||||
if err != nil && auth_verbose { |
|
||||
log.Println("AUTH: Quitting: bouncing QUIT message:", err) |
|
||||
} |
|
||||
break |
|
||||
} |
|
||||
|
|
||||
version := msg[0] |
|
||||
if version != "1.0" { |
|
||||
panic("AUTH: version != 1.0") |
|
||||
} |
|
||||
|
|
||||
request_id := msg[1] |
|
||||
domain := msg[2] |
|
||||
address := msg[3] |
|
||||
identity := msg[4] |
|
||||
mechanism := msg[5] |
|
||||
credentials := msg[6:] |
|
||||
|
|
||||
username := "" |
|
||||
password := "" |
|
||||
client_key := "" |
|
||||
if mechanism == "PLAIN" { |
|
||||
username = msg[6] |
|
||||
password = msg[7] |
|
||||
} else if mechanism == "CURVE" { |
|
||||
s := msg[6] |
|
||||
if len(s) != 32 { |
|
||||
panic("AUTH: len(client_key) != 32") |
|
||||
} |
|
||||
client_key = Z85encode(s) |
|
||||
} |
|
||||
|
|
||||
allowed := false |
|
||||
denied := false |
|
||||
|
|
||||
if auth_has_allow(domain) { |
|
||||
if auth_is_allowed(domain, address) { |
|
||||
allowed = true |
|
||||
if auth_verbose { |
|
||||
log.Printf("AUTH: PASSED (whitelist) domain=%q address=%q\n", domain, address) |
|
||||
} |
|
||||
} else { |
|
||||
denied = true |
|
||||
if auth_verbose { |
|
||||
log.Printf("AUTH: DENIED (not in whitelist) domain=%q address=%q\n", domain, address) |
|
||||
} |
|
||||
} |
|
||||
} else if auth_has_deny(domain) { |
|
||||
if auth_is_denied(domain, address) { |
|
||||
denied = true |
|
||||
if auth_verbose { |
|
||||
log.Printf("AUTH: DENIED (blacklist) domain=%q address=%q\n", domain, address) |
|
||||
} |
|
||||
} else { |
|
||||
allowed = true |
|
||||
if auth_verbose { |
|
||||
log.Printf("AUTH: PASSED (not in blacklist) domain=%q address=%q\n", domain, address) |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// Mechanism-specific checks
|
|
||||
if !denied { |
|
||||
if mechanism == "NULL" && !allowed { |
|
||||
// For NULL, we allow if the address wasn't blacklisted
|
|
||||
if auth_verbose { |
|
||||
log.Printf("AUTH: ALLOWED (NULL)\n") |
|
||||
} |
|
||||
allowed = true |
|
||||
} else if mechanism == "PLAIN" { |
|
||||
// For PLAIN, even a whitelisted address must authenticate
|
|
||||
allowed = authenticate_plain(domain, username, password) |
|
||||
} else if mechanism == "CURVE" { |
|
||||
// For CURVE, even a whitelisted address must authenticate
|
|
||||
allowed = authenticate_curve(domain, client_key) |
|
||||
} |
|
||||
} |
|
||||
if allowed { |
|
||||
m := auth_meta_handler(version, request_id, domain, address, identity, mechanism, credentials...) |
|
||||
user_id := "" |
|
||||
if uid, ok := m["User-Id"]; ok { |
|
||||
user_id = uid |
|
||||
delete(m, "User-Id") |
|
||||
} |
|
||||
metadata := make([]byte, 0) |
|
||||
for key, value := range m { |
|
||||
if len(key) < 256 { |
|
||||
metadata = append(metadata, auth_meta_blob(key, value)...) |
|
||||
} |
|
||||
} |
|
||||
auth_handler.SendMessage(version, request_id, "200", "OK", user_id, metadata) |
|
||||
} else { |
|
||||
auth_handler.SendMessage(version, request_id, "400", "NO ACCESS", "", "") |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
err := auth_handler.Close() |
|
||||
if err != nil && auth_verbose { |
|
||||
log.Println("AUTH: Quitting: Close:", err) |
|
||||
} |
|
||||
if auth_verbose { |
|
||||
log.Println("AUTH: Quit") |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
func authenticate_plain(domain, username, password string) bool { |
|
||||
for _, dom := range []string{domain, "*"} { |
|
||||
if m, ok := auth_users[dom]; ok { |
|
||||
if m[username] == password { |
|
||||
if auth_verbose { |
|
||||
log.Printf("AUTH: ALLOWED (PLAIN) domain=%q username=%q password=%q\n", dom, username, password) |
|
||||
} |
|
||||
return true |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
if auth_verbose { |
|
||||
log.Printf("AUTH: DENIED (PLAIN) domain=%q username=%q password=%q\n", domain, username, password) |
|
||||
} |
|
||||
return false |
|
||||
} |
|
||||
|
|
||||
func authenticate_curve(domain, client_key string) bool { |
|
||||
for _, dom := range []string{domain, "*"} { |
|
||||
if m, ok := auth_pubkeys[dom]; ok { |
|
||||
if m[CURVE_ALLOW_ANY] { |
|
||||
if auth_verbose { |
|
||||
log.Printf("AUTH: ALLOWED (CURVE any client) domain=%q\n", dom) |
|
||||
} |
|
||||
return true |
|
||||
} |
|
||||
if m[client_key] { |
|
||||
if auth_verbose { |
|
||||
log.Printf("AUTH: ALLOWED (CURVE) domain=%q client_key=%q\n", dom, client_key) |
|
||||
} |
|
||||
return true |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
if auth_verbose { |
|
||||
log.Printf("AUTH: DENIED (CURVE) domain=%q client_key=%q\n", domain, client_key) |
|
||||
} |
|
||||
return false |
|
||||
} |
|
||||
|
|
||||
// Start authentication.
|
|
||||
//
|
|
||||
// Note that until you add policies, all incoming NULL connections are allowed
|
|
||||
// (classic ZeroMQ behaviour), and all PLAIN and CURVE connections are denied.
|
|
||||
func AuthStart() (err error) { |
|
||||
if auth_init { |
|
||||
if auth_verbose { |
|
||||
log.Println("AUTH: Already running") |
|
||||
} |
|
||||
return errors.New("Auth is already running") |
|
||||
} |
|
||||
|
|
||||
auth_handler, err = NewSocket(REP) |
|
||||
if err != nil { |
|
||||
return |
|
||||
} |
|
||||
auth_handler.SetLinger(0) |
|
||||
err = auth_handler.Bind("inproc://zeromq.zap.01") |
|
||||
if err != nil { |
|
||||
auth_handler.Close() |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
auth_quit, err = NewSocket(REQ) |
|
||||
if err != nil { |
|
||||
auth_handler.Close() |
|
||||
return |
|
||||
} |
|
||||
auth_quit.SetLinger(0) |
|
||||
err = auth_quit.Connect("inproc://zeromq.zap.01") |
|
||||
if err != nil { |
|
||||
auth_handler.Close() |
|
||||
auth_quit.Close() |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
go auth_do_handler() |
|
||||
|
|
||||
if auth_verbose { |
|
||||
log.Println("AUTH: Starting") |
|
||||
} |
|
||||
|
|
||||
auth_init = true |
|
||||
|
|
||||
return |
|
||||
} |
|
||||
|
|
||||
// Stop authentication.
|
|
||||
func AuthStop() { |
|
||||
if !auth_init { |
|
||||
if auth_verbose { |
|
||||
log.Println("AUTH: Not running, can't stop") |
|
||||
} |
|
||||
return |
|
||||
} |
|
||||
if auth_verbose { |
|
||||
log.Println("AUTH: Stopping") |
|
||||
} |
|
||||
_, err := auth_quit.SendMessageDontwait("QUIT") |
|
||||
if err != nil && auth_verbose { |
|
||||
log.Println("AUTH: Stopping: SendMessageDontwait(\"QUIT\"):", err) |
|
||||
} |
|
||||
_, err = auth_quit.RecvMessage(0) |
|
||||
if err != nil && auth_verbose { |
|
||||
log.Println("AUTH: Stopping: RecvMessage:", err) |
|
||||
} |
|
||||
err = auth_quit.Close() |
|
||||
if err != nil && auth_verbose { |
|
||||
log.Println("AUTH: Stopping: Close:", err) |
|
||||
} |
|
||||
if auth_verbose { |
|
||||
log.Println("AUTH: Stopped") |
|
||||
} |
|
||||
|
|
||||
auth_init = false |
|
||||
|
|
||||
} |
|
||||
|
|
||||
// Allow (whitelist) some addresses for a domain.
|
|
||||
//
|
|
||||
// An address can be a single IP address, or an IP address and mask in CIDR notation.
|
|
||||
//
|
|
||||
// For NULL, all clients from these addresses will be accepted.
|
|
||||
//
|
|
||||
// For PLAIN and CURVE, they will be allowed to continue with authentication.
|
|
||||
//
|
|
||||
// You can call this method multiple times to whitelist multiple IP addresses.
|
|
||||
//
|
|
||||
// If you whitelist a single address for a domain, any non-whitelisted addresses
|
|
||||
// for that domain are treated as blacklisted.
|
|
||||
//
|
|
||||
// Use domain "*" for all domains.
|
|
||||
//
|
|
||||
// For backward compatibility: if domain can be parsed as an IP address, it will be
|
|
||||
// interpreted as another address, and it and all remaining addresses will be added
|
|
||||
// to all domains.
|
|
||||
func AuthAllow(domain string, addresses ...string) { |
|
||||
if auth_isIP(domain) { |
|
||||
auth_allow_for_domain("*", domain) |
|
||||
auth_allow_for_domain("*", addresses...) |
|
||||
} else { |
|
||||
auth_allow_for_domain(domain, addresses...) |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
func auth_allow_for_domain(domain string, addresses ...string) { |
|
||||
if _, ok := auth_allow[domain]; !ok { |
|
||||
auth_allow[domain] = make(map[string]bool) |
|
||||
auth_allow_net[domain] = make([]*net.IPNet, 0) |
|
||||
} |
|
||||
for _, address := range addresses { |
|
||||
if _, ipnet, err := net.ParseCIDR(address); err == nil { |
|
||||
auth_allow_net[domain] = append(auth_allow_net[domain], ipnet) |
|
||||
} else if net.ParseIP(address) != nil { |
|
||||
auth_allow[domain][address] = true |
|
||||
} else { |
|
||||
if auth_verbose { |
|
||||
log.Printf("AUTH: Allow for domain %q: %q is not a valid address or network\n", domain, address) |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// Deny (blacklist) some addresses for a domain.
|
|
||||
//
|
|
||||
// An address can be a single IP address, or an IP address and mask in CIDR notation.
|
|
||||
//
|
|
||||
// For all security mechanisms, this rejects the connection without any further authentication.
|
|
||||
//
|
|
||||
// Use either a whitelist for a domain, or a blacklist for a domain, not both.
|
|
||||
// If you define both a whitelist and a blacklist for a domain, only the whitelist takes effect.
|
|
||||
//
|
|
||||
// Use domain "*" for all domains.
|
|
||||
//
|
|
||||
// For backward compatibility: if domain can be parsed as an IP address, it will be
|
|
||||
// interpreted as another address, and it and all remaining addresses will be added
|
|
||||
// to all domains.
|
|
||||
func AuthDeny(domain string, addresses ...string) { |
|
||||
if auth_isIP(domain) { |
|
||||
auth_deny_for_domain("*", domain) |
|
||||
auth_deny_for_domain("*", addresses...) |
|
||||
} else { |
|
||||
auth_deny_for_domain(domain, addresses...) |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
func auth_deny_for_domain(domain string, addresses ...string) { |
|
||||
if _, ok := auth_deny[domain]; !ok { |
|
||||
auth_deny[domain] = make(map[string]bool) |
|
||||
auth_deny_net[domain] = make([]*net.IPNet, 0) |
|
||||
} |
|
||||
for _, address := range addresses { |
|
||||
if _, ipnet, err := net.ParseCIDR(address); err == nil { |
|
||||
auth_deny_net[domain] = append(auth_deny_net[domain], ipnet) |
|
||||
} else if net.ParseIP(address) != nil { |
|
||||
auth_deny[domain][address] = true |
|
||||
} else { |
|
||||
if auth_verbose { |
|
||||
log.Printf("AUTH: Deny for domain %q: %q is not a valid address or network\n", domain, address) |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// Add a user for PLAIN authentication for a given domain.
|
|
||||
//
|
|
||||
// Set `domain` to "*" to apply to all domains.
|
|
||||
func AuthPlainAdd(domain, username, password string) { |
|
||||
if _, ok := auth_users[domain]; !ok { |
|
||||
auth_users[domain] = make(map[string]string) |
|
||||
} |
|
||||
auth_users[domain][username] = password |
|
||||
} |
|
||||
|
|
||||
// Remove users from PLAIN authentication for a given domain.
|
|
||||
func AuthPlainRemove(domain string, usernames ...string) { |
|
||||
if u, ok := auth_users[domain]; ok { |
|
||||
for _, username := range usernames { |
|
||||
delete(u, username) |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// Remove all users from PLAIN authentication for a given domain.
|
|
||||
func AuthPlainRemoveAll(domain string) { |
|
||||
delete(auth_users, domain) |
|
||||
} |
|
||||
|
|
||||
// Add public user keys for CURVE authentication for a given domain.
|
|
||||
//
|
|
||||
// To cover all domains, use "*".
|
|
||||
//
|
|
||||
// Public keys are in Z85 printable text format.
|
|
||||
//
|
|
||||
// To allow all client keys without checking, specify CURVE_ALLOW_ANY for the key.
|
|
||||
func AuthCurveAdd(domain string, pubkeys ...string) { |
|
||||
if _, ok := auth_pubkeys[domain]; !ok { |
|
||||
auth_pubkeys[domain] = make(map[string]bool) |
|
||||
} |
|
||||
for _, key := range pubkeys { |
|
||||
auth_pubkeys[domain][key] = true |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// Remove user keys from CURVE authentication for a given domain.
|
|
||||
func AuthCurveRemove(domain string, pubkeys ...string) { |
|
||||
if p, ok := auth_pubkeys[domain]; ok { |
|
||||
for _, pubkey := range pubkeys { |
|
||||
delete(p, pubkey) |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// Remove all user keys from CURVE authentication for a given domain.
|
|
||||
func AuthCurveRemoveAll(domain string) { |
|
||||
delete(auth_pubkeys, domain) |
|
||||
} |
|
||||
|
|
||||
// Enable verbose tracing of commands and activity.
|
|
||||
func AuthSetVerbose(verbose bool) { |
|
||||
auth_verbose = verbose |
|
||||
} |
|
||||
|
|
||||
/* |
|
||||
This function sets the metadata handler that is called by the ZAP |
|
||||
handler to retrieve key/value properties that should be set on reply |
|
||||
messages in case of a status code "200" (succes). |
|
||||
|
|
||||
Default properties are `Socket-Type`, which is already set, and |
|
||||
`Identity` and `User-Id` that are empty by default. The last two can be |
|
||||
set, and more properties can be added. |
|
||||
|
|
||||
The `User-Id` property is used for the `user id` frame of the reply |
|
||||
message. All other properties are stored in the `metadata` frame of the |
|
||||
reply message. |
|
||||
|
|
||||
The default handler returns an empty map. |
|
||||
|
|
||||
For the meaning of the handler arguments, and other details, see: |
|
||||
http://rfc.zeromq.org/spec:27#toc10
|
|
||||
*/ |
|
||||
func AuthSetMetadataHandler( |
|
||||
handler func( |
|
||||
version, request_id, domain, address, identity, mechanism string, credentials ...string) (metadata map[string]string)) { |
|
||||
auth_meta_handler = handler |
|
||||
} |
|
||||
|
|
||||
/* |
|
||||
This encodes a key/value pair into the format used by a ZAP handler. |
|
||||
|
|
||||
Returns an error if key is more then 255 characters long. |
|
||||
*/ |
|
||||
func AuthMetaBlob(key, value string) (blob []byte, err error) { |
|
||||
if len(key) > 255 { |
|
||||
return []byte{}, errors.New("Key too long") |
|
||||
} |
|
||||
return auth_meta_blob(key, value), nil |
|
||||
} |
|
||||
|
|
||||
func auth_meta_blob(name, value string) []byte { |
|
||||
l1 := len(name) |
|
||||
l2 := len(value) |
|
||||
b := make([]byte, l1+l2+5) |
|
||||
b[0] = byte(l1) |
|
||||
b[l1+1] = byte(l2 >> 24 & 255) |
|
||||
b[l1+2] = byte(l2 >> 16 & 255) |
|
||||
b[l1+3] = byte(l2 >> 8 & 255) |
|
||||
b[l1+4] = byte(l2 & 255) |
|
||||
copy(b[1:], []byte(name)) |
|
||||
copy(b[5+l1:], []byte(value)) |
|
||||
return b |
|
||||
} |
|
||||
|
|
||||
//. Additional functions for configuring server or client socket with a single command
|
|
||||
|
|
||||
// Set NULL server role.
|
|
||||
func (server *Socket) ServerAuthNull(domain string) error { |
|
||||
err := server.SetPlainServer(0) |
|
||||
if err == nil { |
|
||||
err = server.SetZapDomain(domain) |
|
||||
} |
|
||||
return err |
|
||||
} |
|
||||
|
|
||||
// Set PLAIN server role.
|
|
||||
func (server *Socket) ServerAuthPlain(domain string) error { |
|
||||
err := server.SetPlainServer(1) |
|
||||
if err == nil { |
|
||||
err = server.SetZapDomain(domain) |
|
||||
} |
|
||||
return err |
|
||||
} |
|
||||
|
|
||||
// Set CURVE server role.
|
|
||||
func (server *Socket) ServerAuthCurve(domain, secret_key string) error { |
|
||||
err := server.SetCurveServer(1) |
|
||||
if err == nil { |
|
||||
err = server.SetCurveSecretkey(secret_key) |
|
||||
} |
|
||||
if err == nil { |
|
||||
err = server.SetZapDomain(domain) |
|
||||
} |
|
||||
return err |
|
||||
} |
|
||||
|
|
||||
// Set PLAIN client role.
|
|
||||
func (client *Socket) ClientAuthPlain(username, password string) error { |
|
||||
err := client.SetPlainUsername(username) |
|
||||
if err == nil { |
|
||||
err = client.SetPlainPassword(password) |
|
||||
} |
|
||||
return err |
|
||||
} |
|
||||
|
|
||||
// Set CURVE client role.
|
|
||||
func (client *Socket) ClientAuthCurve(server_public_key, client_public_key, client_secret_key string) error { |
|
||||
err := client.SetCurveServerkey(server_public_key) |
|
||||
if err == nil { |
|
||||
err = client.SetCurvePublickey(client_public_key) |
|
||||
} |
|
||||
if err == nil { |
|
||||
client.SetCurveSecretkey(client_secret_key) |
|
||||
} |
|
||||
return err |
|
||||
} |
|
||||
|
|
||||
// Helper function to derive z85 public key from secret key
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
func AuthCurvePublic(z85SecretKey string) (z85PublicKey string, err error) { |
|
||||
if minor < 2 { |
|
||||
return "", ErrorNotImplemented42 |
|
||||
} |
|
||||
secret := C.CString(z85SecretKey) |
|
||||
defer C.free(unsafe.Pointer(secret)) |
|
||||
public := C.CString(strings.Repeat(" ", 41)) |
|
||||
defer C.free(unsafe.Pointer(public)) |
|
||||
if i, err := C.zmq_curve_public(public, secret); int(i) != 0 { |
|
||||
return "", errget(err) |
|
||||
} |
|
||||
z85PublicKey = C.GoString(public) |
|
||||
return z85PublicKey, nil |
|
||||
} |
|
@ -1,56 +0,0 @@ |
|||||
// +build !windows
|
|
||||
|
|
||||
package zmq4 |
|
||||
|
|
||||
/* |
|
||||
#include <zmq.h> |
|
||||
#include "zmq4.h" |
|
||||
*/ |
|
||||
import "C" |
|
||||
|
|
||||
/* |
|
||||
Sets the scheduling policy for internal context’s thread pool. |
|
||||
|
|
||||
This option requires ZeroMQ version 4.1, and is not available on Windows. |
|
||||
|
|
||||
Supported values for this option can be found in sched.h file, or at |
|
||||
http://man7.org/linux/man-pages/man2/sched_setscheduler.2.html
|
|
||||
|
|
||||
This option only applies before creating any sockets on the context. |
|
||||
|
|
||||
Default value: -1 |
|
||||
|
|
||||
Returns ErrorNotImplemented41 with ZeroMQ version < 4.1 |
|
||||
|
|
||||
Returns ErrorNotImplementedWindows on Windows |
|
||||
*/ |
|
||||
func (ctx *Context) SetThreadSchedPolicy(n int) error { |
|
||||
if minor < 1 { |
|
||||
return ErrorNotImplemented41 |
|
||||
} |
|
||||
return setOption(ctx, C.ZMQ_THREAD_SCHED_POLICY, n) |
|
||||
} |
|
||||
|
|
||||
/* |
|
||||
Sets scheduling priority for internal context’s thread pool. |
|
||||
|
|
||||
This option requires ZeroMQ version 4.1, and is not available on Windows. |
|
||||
|
|
||||
Supported values for this option depend on chosen scheduling policy. |
|
||||
Details can be found in sched.h file, or at |
|
||||
http://man7.org/linux/man-pages/man2/sched_setscheduler.2.html
|
|
||||
|
|
||||
This option only applies before creating any sockets on the context. |
|
||||
|
|
||||
Default value: -1 |
|
||||
|
|
||||
Returns ErrorNotImplemented41 with ZeroMQ version < 4.1 |
|
||||
|
|
||||
Returns ErrorNotImplementedWindows on Windows |
|
||||
*/ |
|
||||
func (ctx *Context) SetThreadPriority(n int) error { |
|
||||
if minor < 1 { |
|
||||
return ErrorNotImplemented41 |
|
||||
} |
|
||||
return setOption(ctx, C.ZMQ_THREAD_PRIORITY, n) |
|
||||
} |
|
@ -1,44 +0,0 @@ |
|||||
// +build windows
|
|
||||
|
|
||||
package zmq4 |
|
||||
|
|
||||
/* |
|
||||
Sets the scheduling policy for internal context’s thread pool. |
|
||||
|
|
||||
This option requires ZeroMQ version 4.1, and is not available on Windows. |
|
||||
|
|
||||
Supported values for this option can be found in sched.h file, or at |
|
||||
http://man7.org/linux/man-pages/man2/sched_setscheduler.2.html
|
|
||||
|
|
||||
This option only applies before creating any sockets on the context. |
|
||||
|
|
||||
Default value: -1 |
|
||||
|
|
||||
Returns ErrorNotImplemented41 with ZeroMQ version < 4.1 |
|
||||
|
|
||||
Returns ErrorNotImplementedWindows on Windows |
|
||||
*/ |
|
||||
func (ctx *Context) SetThreadSchedPolicy(n int) error { |
|
||||
return ErrorNotImplementedWindows |
|
||||
} |
|
||||
|
|
||||
/* |
|
||||
Sets scheduling priority for internal context’s thread pool. |
|
||||
|
|
||||
This option requires ZeroMQ version 4.1, and is not available on Windows. |
|
||||
|
|
||||
Supported values for this option depend on chosen scheduling policy. |
|
||||
Details can be found in sched.h file, or at |
|
||||
http://man7.org/linux/man-pages/man2/sched_setscheduler.2.html
|
|
||||
|
|
||||
This option only applies before creating any sockets on the context. |
|
||||
|
|
||||
Default value: -1 |
|
||||
|
|
||||
Returns ErrorNotImplemented41 with ZeroMQ version < 4.1 |
|
||||
|
|
||||
Returns ErrorNotImplementedWindows on Windows |
|
||||
*/ |
|
||||
func (ctx *Context) SetThreadPriority(n int) error { |
|
||||
return ErrorNotImplementedWindows |
|
||||
} |
|
@ -1,20 +0,0 @@ |
|||||
/* |
|
||||
A Go interface to ZeroMQ (zmq, 0mq) version 4. |
|
||||
|
|
||||
For ZeroMQ version 3, see: http://github.com/pebbe/zmq3
|
|
||||
|
|
||||
For ZeroMQ version 2, see: http://github.com/pebbe/zmq2
|
|
||||
|
|
||||
http://www.zeromq.org/
|
|
||||
|
|
||||
See also the wiki: https://github.com/pebbe/zmq4/wiki
|
|
||||
|
|
||||
A note on the use of a context: |
|
||||
|
|
||||
This package provides a default context. This is what will be used by |
|
||||
the functions without a context receiver, that create a socket or |
|
||||
manipulate the context. Package developers that import this package |
|
||||
should probably not use the default context with its associated |
|
||||
functions, but create their own context(s). See: type Context. |
|
||||
*/ |
|
||||
package zmq4 |
|
@ -1,5 +0,0 @@ |
|||||
/*
|
|
||||
|
|
||||
You need CGO_ENABLED=1 to build this package |
|
||||
|
|
||||
*/ |
|
@ -1,92 +0,0 @@ |
|||||
package zmq4 |
|
||||
|
|
||||
/* |
|
||||
#include <zmq.h> |
|
||||
*/ |
|
||||
import "C" |
|
||||
|
|
||||
import ( |
|
||||
"syscall" |
|
||||
) |
|
||||
|
|
||||
// An Errno is an unsigned number describing an error condition as returned by a call to ZeroMQ.
|
|
||||
// It implements the error interface.
|
|
||||
// The number is either a standard system error, or an error defined by the C library of ZeroMQ.
|
|
||||
type Errno uintptr |
|
||||
|
|
||||
const ( |
|
||||
// Error conditions defined by the C library of ZeroMQ.
|
|
||||
|
|
||||
// On Windows platform some of the standard POSIX errnos are not defined.
|
|
||||
EADDRINUSE = Errno(C.EADDRINUSE) |
|
||||
EADDRNOTAVAIL = Errno(C.EADDRNOTAVAIL) |
|
||||
EAFNOSUPPORT = Errno(C.EAFNOSUPPORT) |
|
||||
ECONNABORTED = Errno(C.ECONNABORTED) |
|
||||
ECONNREFUSED = Errno(C.ECONNREFUSED) |
|
||||
ECONNRESET = Errno(C.ECONNRESET) |
|
||||
EHOSTUNREACH = Errno(C.EHOSTUNREACH) |
|
||||
EINPROGRESS = Errno(C.EINPROGRESS) |
|
||||
EMSGSIZE = Errno(C.EMSGSIZE) |
|
||||
ENETDOWN = Errno(C.ENETDOWN) |
|
||||
ENETRESET = Errno(C.ENETRESET) |
|
||||
ENETUNREACH = Errno(C.ENETUNREACH) |
|
||||
ENOBUFS = Errno(C.ENOBUFS) |
|
||||
ENOTCONN = Errno(C.ENOTCONN) |
|
||||
ENOTSOCK = Errno(C.ENOTSOCK) |
|
||||
ENOTSUP = Errno(C.ENOTSUP) |
|
||||
EPROTONOSUPPORT = Errno(C.EPROTONOSUPPORT) |
|
||||
ETIMEDOUT = Errno(C.ETIMEDOUT) |
|
||||
|
|
||||
// Native 0MQ error codes.
|
|
||||
EFSM = Errno(C.EFSM) |
|
||||
EMTHREAD = Errno(C.EMTHREAD) |
|
||||
ENOCOMPATPROTO = Errno(C.ENOCOMPATPROTO) |
|
||||
ETERM = Errno(C.ETERM) |
|
||||
) |
|
||||
|
|
||||
func errget(err error) error { |
|
||||
eno, ok := err.(syscall.Errno) |
|
||||
if ok { |
|
||||
return Errno(eno) |
|
||||
} |
|
||||
return err |
|
||||
} |
|
||||
|
|
||||
// Return Errno as string.
|
|
||||
func (errno Errno) Error() string { |
|
||||
if errno >= C.ZMQ_HAUSNUMERO { |
|
||||
return C.GoString(C.zmq_strerror(C.int(errno))) |
|
||||
} |
|
||||
return syscall.Errno(errno).Error() |
|
||||
} |
|
||||
|
|
||||
/* |
|
||||
Convert error to Errno. |
|
||||
|
|
||||
Example usage: |
|
||||
|
|
||||
switch AsErrno(err) { |
|
||||
|
|
||||
case zmq.Errno(syscall.EINTR): |
|
||||
// standard system error
|
|
||||
|
|
||||
// call was interrupted
|
|
||||
|
|
||||
case zmq.ETERM: |
|
||||
// error defined by ZeroMQ
|
|
||||
|
|
||||
// context was terminated
|
|
||||
|
|
||||
} |
|
||||
|
|
||||
See also: examples/interrupt.go |
|
||||
*/ |
|
||||
func AsErrno(err error) Errno { |
|
||||
if eno, ok := err.(Errno); ok { |
|
||||
return eno |
|
||||
} |
|
||||
if eno, ok := err.(syscall.Errno); ok { |
|
||||
return Errno(eno) |
|
||||
} |
|
||||
return Errno(0) |
|
||||
} |
|
@ -1,187 +0,0 @@ |
|||||
package zmq4 |
|
||||
|
|
||||
/* |
|
||||
#include <zmq.h> |
|
||||
*/ |
|
||||
import "C" |
|
||||
|
|
||||
import ( |
|
||||
"fmt" |
|
||||
"time" |
|
||||
) |
|
||||
|
|
||||
// Return type for (*Poller)Poll
|
|
||||
type Polled struct { |
|
||||
Socket *Socket // socket with matched event(s)
|
|
||||
Events State // actual matched event(s)
|
|
||||
} |
|
||||
|
|
||||
type Poller struct { |
|
||||
items []C.zmq_pollitem_t |
|
||||
socks []*Socket |
|
||||
} |
|
||||
|
|
||||
// Create a new Poller
|
|
||||
func NewPoller() *Poller { |
|
||||
return &Poller{ |
|
||||
items: make([]C.zmq_pollitem_t, 0), |
|
||||
socks: make([]*Socket, 0), |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// Add items to the poller
|
|
||||
//
|
|
||||
// Events is a bitwise OR of zmq.POLLIN and zmq.POLLOUT
|
|
||||
//
|
|
||||
// Returns the id of the item, which can be used as a handle to
|
|
||||
// (*Poller)Update and as an index into the result of (*Poller)PollAll
|
|
||||
func (p *Poller) Add(soc *Socket, events State) int { |
|
||||
var item C.zmq_pollitem_t |
|
||||
item.socket = soc.soc |
|
||||
item.fd = 0 |
|
||||
item.events = C.short(events) |
|
||||
p.items = append(p.items, item) |
|
||||
p.socks = append(p.socks, soc) |
|
||||
return len(p.items) - 1 |
|
||||
} |
|
||||
|
|
||||
// Update the events mask of a socket in the poller
|
|
||||
//
|
|
||||
// Replaces the Poller's bitmask for the specified id with the events parameter passed
|
|
||||
//
|
|
||||
// Returns the previous value, or ErrorNoSocket if the id was out of range
|
|
||||
func (p *Poller) Update(id int, events State) (previous State, err error) { |
|
||||
if id >= 0 && id < len(p.items) { |
|
||||
previous = State(p.items[id].events) |
|
||||
p.items[id].events = C.short(events) |
|
||||
return previous, nil |
|
||||
} |
|
||||
return 0, ErrorNoSocket |
|
||||
} |
|
||||
|
|
||||
// Update the events mask of a socket in the poller
|
|
||||
//
|
|
||||
// Replaces the Poller's bitmask for the specified socket with the events parameter passed
|
|
||||
//
|
|
||||
// Returns the previous value, or ErrorNoSocket if the socket didn't match
|
|
||||
func (p *Poller) UpdateBySocket(soc *Socket, events State) (previous State, err error) { |
|
||||
for id, s := range p.socks { |
|
||||
if s == soc { |
|
||||
previous = State(p.items[id].events) |
|
||||
p.items[id].events = C.short(events) |
|
||||
return previous, nil |
|
||||
} |
|
||||
} |
|
||||
return 0, ErrorNoSocket |
|
||||
} |
|
||||
|
|
||||
// Remove a socket from the poller
|
|
||||
//
|
|
||||
// Returns ErrorNoSocket if the id was out of range
|
|
||||
func (p *Poller) Remove(id int) error { |
|
||||
if id >= 0 && id < len(p.items) { |
|
||||
if id == len(p.items)-1 { |
|
||||
p.items = p.items[:id] |
|
||||
p.socks = p.socks[:id] |
|
||||
} else { |
|
||||
p.items = append(p.items[:id], p.items[id+1:]...) |
|
||||
p.socks = append(p.socks[:id], p.socks[id+1:]...) |
|
||||
} |
|
||||
return nil |
|
||||
} |
|
||||
return ErrorNoSocket |
|
||||
} |
|
||||
|
|
||||
// Remove a socket from the poller
|
|
||||
//
|
|
||||
// Returns ErrorNoSocket if the socket didn't match
|
|
||||
func (p *Poller) RemoveBySocket(soc *Socket) error { |
|
||||
for id, s := range p.socks { |
|
||||
if s == soc { |
|
||||
return p.Remove(id) |
|
||||
} |
|
||||
} |
|
||||
return ErrorNoSocket |
|
||||
} |
|
||||
|
|
||||
/* |
|
||||
Input/output multiplexing |
|
||||
|
|
||||
If timeout < 0, wait forever until a matching event is detected |
|
||||
|
|
||||
Only sockets with matching socket events are returned in the list. |
|
||||
|
|
||||
Example: |
|
||||
|
|
||||
poller := zmq.NewPoller() |
|
||||
poller.Add(socket0, zmq.POLLIN) |
|
||||
poller.Add(socket1, zmq.POLLIN) |
|
||||
// Process messages from both sockets
|
|
||||
for { |
|
||||
sockets, _ := poller.Poll(-1) |
|
||||
for _, socket := range sockets { |
|
||||
switch s := socket.Socket; s { |
|
||||
case socket0: |
|
||||
msg, _ := s.Recv(0) |
|
||||
// Process msg
|
|
||||
case socket1: |
|
||||
msg, _ := s.Recv(0) |
|
||||
// Process msg
|
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
*/ |
|
||||
func (p *Poller) Poll(timeout time.Duration) ([]Polled, error) { |
|
||||
return p.poll(timeout, false) |
|
||||
} |
|
||||
|
|
||||
/* |
|
||||
This is like (*Poller)Poll, but it returns a list of all sockets, |
|
||||
in the same order as they were added to the poller, |
|
||||
not just those sockets that had an event. |
|
||||
|
|
||||
For each socket in the list, you have to check the Events field |
|
||||
to see if there was actually an event. |
|
||||
|
|
||||
When error is not nil, the return list contains no sockets. |
|
||||
*/ |
|
||||
func (p *Poller) PollAll(timeout time.Duration) ([]Polled, error) { |
|
||||
return p.poll(timeout, true) |
|
||||
} |
|
||||
|
|
||||
func (p *Poller) poll(timeout time.Duration, all bool) ([]Polled, error) { |
|
||||
lst := make([]Polled, 0, len(p.items)) |
|
||||
|
|
||||
for _, soc := range p.socks { |
|
||||
if !soc.opened { |
|
||||
return lst, ErrorSocketClosed |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
t := timeout |
|
||||
if t > 0 { |
|
||||
t = t / time.Millisecond |
|
||||
} |
|
||||
if t < 0 { |
|
||||
t = -1 |
|
||||
} |
|
||||
rv, err := C.zmq_poll(&p.items[0], C.int(len(p.items)), C.long(t)) |
|
||||
if rv < 0 { |
|
||||
return lst, errget(err) |
|
||||
} |
|
||||
for i, it := range p.items { |
|
||||
if all || it.events&it.revents != 0 { |
|
||||
lst = append(lst, Polled{p.socks[i], State(it.revents)}) |
|
||||
} |
|
||||
} |
|
||||
return lst, nil |
|
||||
} |
|
||||
|
|
||||
// Poller as string.
|
|
||||
func (p *Poller) String() string { |
|
||||
str := make([]string, 0) |
|
||||
for i, poll := range p.items { |
|
||||
str = append(str, fmt.Sprintf("%v%v", p.socks[i], State(poll.events))) |
|
||||
} |
|
||||
return fmt.Sprint("Poller", str) |
|
||||
} |
|
@ -1,194 +0,0 @@ |
|||||
package zmq4 |
|
||||
|
|
||||
import ( |
|
||||
"errors" |
|
||||
"fmt" |
|
||||
"time" |
|
||||
) |
|
||||
|
|
||||
type reactor_socket struct { |
|
||||
e State |
|
||||
f func(State) error |
|
||||
} |
|
||||
|
|
||||
type reactor_channel struct { |
|
||||
ch <-chan interface{} |
|
||||
f func(interface{}) error |
|
||||
limit int |
|
||||
} |
|
||||
|
|
||||
type Reactor struct { |
|
||||
sockets map[*Socket]*reactor_socket |
|
||||
channels map[uint64]*reactor_channel |
|
||||
p *Poller |
|
||||
idx uint64 |
|
||||
remove []uint64 |
|
||||
verbose bool |
|
||||
} |
|
||||
|
|
||||
/* |
|
||||
Create a reactor to mix the handling of sockets and channels (timers or other channels). |
|
||||
|
|
||||
Example: |
|
||||
|
|
||||
reactor := zmq.NewReactor() |
|
||||
reactor.AddSocket(socket1, zmq.POLLIN, socket1_handler) |
|
||||
reactor.AddSocket(socket2, zmq.POLLIN, socket2_handler) |
|
||||
reactor.AddChannelTime(time.Tick(time.Second), 1, ticker_handler) |
|
||||
reactor.Run(time.Second) |
|
||||
*/ |
|
||||
func NewReactor() *Reactor { |
|
||||
r := &Reactor{ |
|
||||
sockets: make(map[*Socket]*reactor_socket), |
|
||||
channels: make(map[uint64]*reactor_channel), |
|
||||
p: NewPoller(), |
|
||||
remove: make([]uint64, 0), |
|
||||
} |
|
||||
return r |
|
||||
} |
|
||||
|
|
||||
// Add socket handler to the reactor.
|
|
||||
//
|
|
||||
// You can have only one handler per socket. Adding a second one will remove the first.
|
|
||||
//
|
|
||||
// The handler receives the socket state as an argument: POLLIN, POLLOUT, or both.
|
|
||||
func (r *Reactor) AddSocket(soc *Socket, events State, handler func(State) error) { |
|
||||
r.RemoveSocket(soc) |
|
||||
r.sockets[soc] = &reactor_socket{e: events, f: handler} |
|
||||
r.p.Add(soc, events) |
|
||||
} |
|
||||
|
|
||||
// Remove a socket handler from the reactor.
|
|
||||
func (r *Reactor) RemoveSocket(soc *Socket) { |
|
||||
if _, ok := r.sockets[soc]; ok { |
|
||||
delete(r.sockets, soc) |
|
||||
// rebuild poller
|
|
||||
r.p = NewPoller() |
|
||||
for s, props := range r.sockets { |
|
||||
r.p.Add(s, props.e) |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// Add channel handler to the reactor.
|
|
||||
//
|
|
||||
// Returns id of added handler, that can be used later to remove it.
|
|
||||
//
|
|
||||
// If limit is positive, at most this many items will be handled in each run through the main loop,
|
|
||||
// otherwise it will process as many items as possible.
|
|
||||
//
|
|
||||
// The handler function receives the value received from the channel.
|
|
||||
func (r *Reactor) AddChannel(ch <-chan interface{}, limit int, handler func(interface{}) error) (id uint64) { |
|
||||
r.idx++ |
|
||||
id = r.idx |
|
||||
r.channels[id] = &reactor_channel{ch: ch, f: handler, limit: limit} |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
// This function wraps AddChannel, using a channel of type time.Time instead of type interface{}.
|
|
||||
func (r *Reactor) AddChannelTime(ch <-chan time.Time, limit int, handler func(interface{}) error) (id uint64) { |
|
||||
ch2 := make(chan interface{}) |
|
||||
go func() { |
|
||||
for { |
|
||||
a, ok := <-ch |
|
||||
if !ok { |
|
||||
close(ch2) |
|
||||
break |
|
||||
} |
|
||||
ch2 <- a |
|
||||
} |
|
||||
}() |
|
||||
return r.AddChannel(ch2, limit, handler) |
|
||||
} |
|
||||
|
|
||||
// Remove a channel from the reactor.
|
|
||||
//
|
|
||||
// Closed channels are removed automatically.
|
|
||||
func (r *Reactor) RemoveChannel(id uint64) { |
|
||||
r.remove = append(r.remove, id) |
|
||||
} |
|
||||
|
|
||||
func (r *Reactor) SetVerbose(verbose bool) { |
|
||||
r.verbose = verbose |
|
||||
} |
|
||||
|
|
||||
// Run the reactor.
|
|
||||
//
|
|
||||
// The interval determines the time-out on the polling of sockets.
|
|
||||
// Interval must be positive if there are channels.
|
|
||||
// If there are no channels, you can set interval to -1.
|
|
||||
//
|
|
||||
// The run alternates between polling/handling sockets (using the interval as timeout),
|
|
||||
// and reading/handling channels. The reading of channels is without time-out: if there
|
|
||||
// is no activity on any channel, the run continues to poll sockets immediately.
|
|
||||
//
|
|
||||
// The run exits when any handler returns an error, returning that same error.
|
|
||||
func (r *Reactor) Run(interval time.Duration) (err error) { |
|
||||
for { |
|
||||
|
|
||||
// process requests to remove channels
|
|
||||
for _, id := range r.remove { |
|
||||
delete(r.channels, id) |
|
||||
} |
|
||||
r.remove = r.remove[0:0] |
|
||||
|
|
||||
CHANNELS: |
|
||||
for id, ch := range r.channels { |
|
||||
limit := ch.limit |
|
||||
for { |
|
||||
select { |
|
||||
case val, ok := <-ch.ch: |
|
||||
if !ok { |
|
||||
if r.verbose { |
|
||||
fmt.Printf("Reactor(%p) removing closed channel %d\n", r, id) |
|
||||
} |
|
||||
r.RemoveChannel(id) |
|
||||
continue CHANNELS |
|
||||
} |
|
||||
if r.verbose { |
|
||||
fmt.Printf("Reactor(%p) channel %d: %q\n", r, id, val) |
|
||||
} |
|
||||
err = ch.f(val) |
|
||||
if err != nil { |
|
||||
return |
|
||||
} |
|
||||
if ch.limit > 0 { |
|
||||
limit-- |
|
||||
if limit == 0 { |
|
||||
continue CHANNELS |
|
||||
} |
|
||||
} |
|
||||
default: |
|
||||
continue CHANNELS |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
if len(r.channels) > 0 && interval < 0 { |
|
||||
return errors.New("There are channels, but polling time-out is infinite") |
|
||||
} |
|
||||
|
|
||||
if len(r.sockets) == 0 { |
|
||||
if len(r.channels) == 0 { |
|
||||
return errors.New("No sockets to poll, no channels to read") |
|
||||
} |
|
||||
time.Sleep(interval) |
|
||||
continue |
|
||||
} |
|
||||
|
|
||||
polled, e := r.p.Poll(interval) |
|
||||
if e != nil { |
|
||||
return e |
|
||||
} |
|
||||
for _, item := range polled { |
|
||||
if r.verbose { |
|
||||
fmt.Printf("Reactor(%p) %v\n", r, item) |
|
||||
} |
|
||||
err = r.sockets[item.Socket].f(item.Events) |
|
||||
if err != nil { |
|
||||
return |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
return |
|
||||
} |
|
@ -1,648 +0,0 @@ |
|||||
package zmq4 |
|
||||
|
|
||||
/* |
|
||||
#include <zmq.h> |
|
||||
#include <stdint.h> |
|
||||
#include "zmq4.h" |
|
||||
*/ |
|
||||
import "C" |
|
||||
|
|
||||
import ( |
|
||||
"strings" |
|
||||
"time" |
|
||||
"unsafe" |
|
||||
) |
|
||||
|
|
||||
func (soc *Socket) getString(opt C.int, bufsize int) (string, error) { |
|
||||
if !soc.opened { |
|
||||
return "", ErrorSocketClosed |
|
||||
} |
|
||||
value := make([]byte, bufsize) |
|
||||
size := C.size_t(bufsize) |
|
||||
if i, err := C.zmq_getsockopt(soc.soc, opt, unsafe.Pointer(&value[0]), &size); i != 0 { |
|
||||
return "", errget(err) |
|
||||
} |
|
||||
return strings.TrimRight(string(value[:int(size)]), "\x00"), nil |
|
||||
} |
|
||||
|
|
||||
func (soc *Socket) getStringRaw(opt C.int, bufsize int) (string, error) { |
|
||||
if !soc.opened { |
|
||||
return "", ErrorSocketClosed |
|
||||
} |
|
||||
value := make([]byte, bufsize) |
|
||||
size := C.size_t(bufsize) |
|
||||
if i, err := C.zmq_getsockopt(soc.soc, opt, unsafe.Pointer(&value[0]), &size); i != 0 { |
|
||||
return "", errget(err) |
|
||||
} |
|
||||
return string(value[:int(size)]), nil |
|
||||
} |
|
||||
|
|
||||
func (soc *Socket) getInt(opt C.int) (int, error) { |
|
||||
if !soc.opened { |
|
||||
return 0, ErrorSocketClosed |
|
||||
} |
|
||||
value := C.int(0) |
|
||||
size := C.size_t(unsafe.Sizeof(value)) |
|
||||
if i, err := C.zmq_getsockopt(soc.soc, opt, unsafe.Pointer(&value), &size); i != 0 { |
|
||||
return 0, errget(err) |
|
||||
} |
|
||||
return int(value), nil |
|
||||
} |
|
||||
|
|
||||
func (soc *Socket) getInt64(opt C.int) (int64, error) { |
|
||||
if !soc.opened { |
|
||||
return 0, ErrorSocketClosed |
|
||||
} |
|
||||
value := C.int64_t(0) |
|
||||
size := C.size_t(unsafe.Sizeof(value)) |
|
||||
if i, err := C.zmq_getsockopt(soc.soc, opt, unsafe.Pointer(&value), &size); i != 0 { |
|
||||
return 0, errget(err) |
|
||||
} |
|
||||
return int64(value), nil |
|
||||
} |
|
||||
|
|
||||
func (soc *Socket) getUInt64(opt C.int) (uint64, error) { |
|
||||
if !soc.opened { |
|
||||
return 0, ErrorSocketClosed |
|
||||
} |
|
||||
value := C.uint64_t(0) |
|
||||
size := C.size_t(unsafe.Sizeof(value)) |
|
||||
if i, err := C.zmq_getsockopt(soc.soc, opt, unsafe.Pointer(&value), &size); i != 0 { |
|
||||
return 0, errget(err) |
|
||||
} |
|
||||
return uint64(value), nil |
|
||||
} |
|
||||
|
|
||||
// ZMQ_TYPE: Retrieve socket type
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc43
|
|
||||
func (soc *Socket) GetType() (Type, error) { |
|
||||
v, err := soc.getInt(C.ZMQ_TYPE) |
|
||||
return Type(v), err |
|
||||
} |
|
||||
|
|
||||
// ZMQ_RCVMORE: More message data parts to follow
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc30
|
|
||||
func (soc *Socket) GetRcvmore() (bool, error) { |
|
||||
v, err := soc.getInt(C.ZMQ_RCVMORE) |
|
||||
return v != 0, err |
|
||||
} |
|
||||
|
|
||||
// ZMQ_SNDHWM: Retrieves high water mark for outbound messages
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc36
|
|
||||
func (soc *Socket) GetSndhwm() (int, error) { |
|
||||
return soc.getInt(C.ZMQ_SNDHWM) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_RCVHWM: Retrieve high water mark for inbound messages
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc29
|
|
||||
func (soc *Socket) GetRcvhwm() (int, error) { |
|
||||
return soc.getInt(C.ZMQ_RCVHWM) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_AFFINITY: Retrieve I/O thread affinity
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc3
|
|
||||
func (soc *Socket) GetAffinity() (uint64, error) { |
|
||||
return soc.getUInt64(C.ZMQ_AFFINITY) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_IDENTITY: Retrieve socket identity
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc15
|
|
||||
func (soc *Socket) GetIdentity() (string, error) { |
|
||||
return soc.getString(C.ZMQ_IDENTITY, 256) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_RATE: Retrieve multicast data rate
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc27
|
|
||||
func (soc *Socket) GetRate() (int, error) { |
|
||||
return soc.getInt(C.ZMQ_RATE) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_RECOVERY_IVL: Get multicast recovery interval
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc34
|
|
||||
func (soc *Socket) GetRecoveryIvl() (time.Duration, error) { |
|
||||
v, err := soc.getInt(C.ZMQ_RECOVERY_IVL) |
|
||||
return time.Duration(v) * time.Millisecond, err |
|
||||
} |
|
||||
|
|
||||
// ZMQ_SNDBUF: Retrieve kernel transmit buffer size
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc35
|
|
||||
func (soc *Socket) GetSndbuf() (int, error) { |
|
||||
return soc.getInt(C.ZMQ_SNDBUF) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_RCVBUF: Retrieve kernel receive buffer size
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc28
|
|
||||
func (soc *Socket) GetRcvbuf() (int, error) { |
|
||||
return soc.getInt(C.ZMQ_RCVBUF) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_LINGER: Retrieve linger period for socket shutdown
|
|
||||
//
|
|
||||
// Returns time.Duration(-1) for infinite
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc20
|
|
||||
func (soc *Socket) GetLinger() (time.Duration, error) { |
|
||||
v, err := soc.getInt(C.ZMQ_LINGER) |
|
||||
if v < 0 { |
|
||||
return time.Duration(-1), err |
|
||||
} |
|
||||
return time.Duration(v) * time.Millisecond, err |
|
||||
} |
|
||||
|
|
||||
// ZMQ_RECONNECT_IVL: Retrieve reconnection interval
|
|
||||
//
|
|
||||
// Returns time.Duration(-1) for no reconnection
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc32
|
|
||||
func (soc *Socket) GetReconnectIvl() (time.Duration, error) { |
|
||||
v, err := soc.getInt(C.ZMQ_RECONNECT_IVL) |
|
||||
if v < 0 { |
|
||||
return time.Duration(-1), err |
|
||||
} |
|
||||
return time.Duration(v) * time.Millisecond, err |
|
||||
} |
|
||||
|
|
||||
// ZMQ_RECONNECT_IVL_MAX: Retrieve maximum reconnection interval
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc33
|
|
||||
func (soc *Socket) GetReconnectIvlMax() (time.Duration, error) { |
|
||||
v, err := soc.getInt(C.ZMQ_RECONNECT_IVL_MAX) |
|
||||
return time.Duration(v) * time.Millisecond, err |
|
||||
} |
|
||||
|
|
||||
// ZMQ_BACKLOG: Retrieve maximum length of the queue of outstanding connections
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc4
|
|
||||
func (soc *Socket) GetBacklog() (int, error) { |
|
||||
return soc.getInt(C.ZMQ_BACKLOG) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_MAXMSGSIZE: Maximum acceptable inbound message size
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc21
|
|
||||
func (soc *Socket) GetMaxmsgsize() (int64, error) { |
|
||||
return soc.getInt64(C.ZMQ_MAXMSGSIZE) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_MULTICAST_HOPS: Maximum network hops for multicast packets
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc23
|
|
||||
func (soc *Socket) GetMulticastHops() (int, error) { |
|
||||
return soc.getInt(C.ZMQ_MULTICAST_HOPS) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_RCVTIMEO: Maximum time before a socket operation returns with EAGAIN
|
|
||||
//
|
|
||||
// Returns time.Duration(-1) for infinite
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc31
|
|
||||
func (soc *Socket) GetRcvtimeo() (time.Duration, error) { |
|
||||
v, err := soc.getInt(C.ZMQ_RCVTIMEO) |
|
||||
if v < 0 { |
|
||||
return time.Duration(-1), err |
|
||||
} |
|
||||
return time.Duration(v) * time.Millisecond, err |
|
||||
} |
|
||||
|
|
||||
// ZMQ_SNDTIMEO: Maximum time before a socket operation returns with EAGAIN
|
|
||||
//
|
|
||||
// Returns time.Duration(-1) for infinite
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc37
|
|
||||
func (soc *Socket) GetSndtimeo() (time.Duration, error) { |
|
||||
v, err := soc.getInt(C.ZMQ_SNDTIMEO) |
|
||||
if v < 0 { |
|
||||
return time.Duration(-1), err |
|
||||
} |
|
||||
return time.Duration(v) * time.Millisecond, err |
|
||||
} |
|
||||
|
|
||||
// ZMQ_IPV6: Retrieve IPv6 socket status
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc18
|
|
||||
func (soc *Socket) GetIpv6() (bool, error) { |
|
||||
v, err := soc.getInt(C.ZMQ_IPV6) |
|
||||
return v != 0, err |
|
||||
} |
|
||||
|
|
||||
// ZMQ_IMMEDIATE: Retrieve attach-on-connect value
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc16
|
|
||||
func (soc *Socket) GetImmediate() (bool, error) { |
|
||||
v, err := soc.getInt(C.ZMQ_IMMEDIATE) |
|
||||
return v != 0, err |
|
||||
} |
|
||||
|
|
||||
// ZMQ_FD: Retrieve file descriptor associated with the socket
|
|
||||
// see socketget_unix.go and socketget_windows.go
|
|
||||
|
|
||||
// ZMQ_EVENTS: Retrieve socket event state
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc8
|
|
||||
func (soc *Socket) GetEvents() (State, error) { |
|
||||
v, err := soc.getInt(C.ZMQ_EVENTS) |
|
||||
return State(v), err |
|
||||
} |
|
||||
|
|
||||
// ZMQ_LAST_ENDPOINT: Retrieve the last endpoint set
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc19
|
|
||||
func (soc *Socket) GetLastEndpoint() (string, error) { |
|
||||
return soc.getString(C.ZMQ_LAST_ENDPOINT, 1024) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_TCP_KEEPALIVE: Override SO_KEEPALIVE socket option
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc38
|
|
||||
func (soc *Socket) GetTcpKeepalive() (int, error) { |
|
||||
return soc.getInt(C.ZMQ_TCP_KEEPALIVE) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_TCP_KEEPALIVE_IDLE: Override TCP_KEEPCNT(or TCP_KEEPALIVE on some OS)
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc40
|
|
||||
func (soc *Socket) GetTcpKeepaliveIdle() (int, error) { |
|
||||
return soc.getInt(C.ZMQ_TCP_KEEPALIVE_IDLE) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_TCP_KEEPALIVE_CNT: Override TCP_KEEPCNT socket option
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc39
|
|
||||
func (soc *Socket) GetTcpKeepaliveCnt() (int, error) { |
|
||||
return soc.getInt(C.ZMQ_TCP_KEEPALIVE_CNT) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_TCP_KEEPALIVE_INTVL: Override TCP_KEEPINTVL socket option
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc41
|
|
||||
func (soc *Socket) GetTcpKeepaliveIntvl() (int, error) { |
|
||||
return soc.getInt(C.ZMQ_TCP_KEEPALIVE_INTVL) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_MECHANISM: Retrieve current security mechanism
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc22
|
|
||||
func (soc *Socket) GetMechanism() (Mechanism, error) { |
|
||||
v, err := soc.getInt(C.ZMQ_MECHANISM) |
|
||||
return Mechanism(v), err |
|
||||
} |
|
||||
|
|
||||
// ZMQ_PLAIN_SERVER: Retrieve current PLAIN server role
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc25
|
|
||||
func (soc *Socket) GetPlainServer() (int, error) { |
|
||||
return soc.getInt(C.ZMQ_PLAIN_SERVER) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_PLAIN_USERNAME: Retrieve current PLAIN username
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc26
|
|
||||
func (soc *Socket) GetPlainUsername() (string, error) { |
|
||||
s, err := soc.getString(C.ZMQ_PLAIN_USERNAME, 1024) |
|
||||
if n := len(s); n > 0 && s[n-1] == 0 { |
|
||||
s = s[:n-1] |
|
||||
} |
|
||||
return s, err |
|
||||
} |
|
||||
|
|
||||
// ZMQ_PLAIN_PASSWORD: Retrieve current password
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc24
|
|
||||
func (soc *Socket) GetPlainPassword() (string, error) { |
|
||||
s, err := soc.getString(C.ZMQ_PLAIN_PASSWORD, 1024) |
|
||||
if n := len(s); n > 0 && s[n-1] == 0 { |
|
||||
s = s[:n-1] |
|
||||
} |
|
||||
return s, err |
|
||||
} |
|
||||
|
|
||||
// ZMQ_CURVE_PUBLICKEY: Retrieve current CURVE public key
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc5
|
|
||||
func (soc *Socket) GetCurvePublickeyRaw() (string, error) { |
|
||||
return soc.getStringRaw(C.ZMQ_CURVE_PUBLICKEY, 32) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_CURVE_PUBLICKEY: Retrieve current CURVE public key
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc5
|
|
||||
func (soc *Socket) GetCurvePublickeykeyZ85() (string, error) { |
|
||||
return soc.getString(C.ZMQ_CURVE_PUBLICKEY, 41) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_CURVE_SECRETKEY: Retrieve current CURVE secret key
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc6
|
|
||||
func (soc *Socket) GetCurveSecretkeyRaw() (string, error) { |
|
||||
return soc.getStringRaw(C.ZMQ_CURVE_SECRETKEY, 32) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_CURVE_SECRETKEY: Retrieve current CURVE secret key
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc6
|
|
||||
func (soc *Socket) GetCurveSecretkeyZ85() (string, error) { |
|
||||
return soc.getString(C.ZMQ_CURVE_SECRETKEY, 41) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_CURVE_SERVERKEY: Retrieve current CURVE server key
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc7
|
|
||||
func (soc *Socket) GetCurveServerkeyRaw() (string, error) { |
|
||||
return soc.getStringRaw(C.ZMQ_CURVE_SERVERKEY, 32) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_CURVE_SERVERKEY: Retrieve current CURVE server key
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc7
|
|
||||
func (soc *Socket) GetCurveServerkeyZ85() (string, error) { |
|
||||
return soc.getString(C.ZMQ_CURVE_SERVERKEY, 41) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_ZAP_DOMAIN: Retrieve RFC 27 authentication domain
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc44
|
|
||||
func (soc *Socket) GetZapDomain() (string, error) { |
|
||||
return soc.getString(C.ZMQ_ZAP_DOMAIN, 1024) |
|
||||
} |
|
||||
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// New in ZeroMQ 4.1.0
|
|
||||
//
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// + : yes
|
|
||||
// D : deprecated
|
|
||||
// o : setsockopt only
|
|
||||
// implemented documented test
|
|
||||
// ZMQ_ROUTER_HANDOVER o
|
|
||||
// ZMQ_TOS + +
|
|
||||
// ZMQ_IPC_FILTER_PID D
|
|
||||
// ZMQ_IPC_FILTER_UID D
|
|
||||
// ZMQ_IPC_FILTER_GID D
|
|
||||
// ZMQ_CONNECT_RID o
|
|
||||
// ZMQ_GSSAPI_SERVER + +
|
|
||||
// ZMQ_GSSAPI_PRINCIPAL + +
|
|
||||
// ZMQ_GSSAPI_SERVICE_PRINCIPAL + +
|
|
||||
// ZMQ_GSSAPI_PLAINTEXT + +
|
|
||||
// ZMQ_HANDSHAKE_IVL + +
|
|
||||
// ZMQ_SOCKS_PROXY +
|
|
||||
// ZMQ_XPUB_NODROP o?
|
|
||||
//
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
// ZMQ_TOS: Retrieve the Type-of-Service socket override status
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented41 with ZeroMQ version < 4.1
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc42
|
|
||||
func (soc *Socket) GetTos() (int, error) { |
|
||||
if minor < 1 { |
|
||||
return 0, ErrorNotImplemented41 |
|
||||
} |
|
||||
return soc.getInt(C.ZMQ_TOS) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_CONNECT_RID: SET ONLY
|
|
||||
|
|
||||
// ZMQ_GSSAPI_SERVER: Retrieve current GSSAPI server role
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented41 with ZeroMQ version < 4.1
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc12
|
|
||||
func (soc *Socket) GetGssapiServer() (bool, error) { |
|
||||
if minor < 1 { |
|
||||
return false, ErrorNotImplemented41 |
|
||||
} |
|
||||
v, err := soc.getInt(C.ZMQ_GSSAPI_SERVER) |
|
||||
return v != 0, err |
|
||||
} |
|
||||
|
|
||||
// ZMQ_GSSAPI_PRINCIPAL: Retrieve the name of the GSSAPI principal
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented41 with ZeroMQ version < 4.1
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc11
|
|
||||
func (soc *Socket) GetGssapiPrincipal() (string, error) { |
|
||||
if minor < 1 { |
|
||||
return "", ErrorNotImplemented41 |
|
||||
} |
|
||||
return soc.getString(C.ZMQ_GSSAPI_PRINCIPAL, 1024) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_GSSAPI_SERVICE_PRINCIPAL: Retrieve the name of the GSSAPI service principal
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented41 with ZeroMQ version < 4.1
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc13
|
|
||||
func (soc *Socket) GetGssapiServicePrincipal() (string, error) { |
|
||||
if minor < 1 { |
|
||||
return "", ErrorNotImplemented41 |
|
||||
} |
|
||||
return soc.getString(C.ZMQ_GSSAPI_SERVICE_PRINCIPAL, 1024) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_GSSAPI_PLAINTEXT: Retrieve GSSAPI plaintext or encrypted status
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented41 with ZeroMQ version < 4.1
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc10
|
|
||||
func (soc *Socket) GetGssapiPlaintext() (bool, error) { |
|
||||
if minor < 1 { |
|
||||
return false, ErrorNotImplemented41 |
|
||||
} |
|
||||
v, err := soc.getInt(C.ZMQ_GSSAPI_PLAINTEXT) |
|
||||
return v != 0, err |
|
||||
} |
|
||||
|
|
||||
// ZMQ_HANDSHAKE_IVL: Retrieve maximum handshake interval
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented41 with ZeroMQ version < 4.1
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc14
|
|
||||
func (soc *Socket) GetHandshakeIvl() (time.Duration, error) { |
|
||||
if minor < 1 { |
|
||||
return time.Duration(0), ErrorNotImplemented41 |
|
||||
} |
|
||||
v, err := soc.getInt(C.ZMQ_HANDSHAKE_IVL) |
|
||||
return time.Duration(v) * time.Millisecond, err |
|
||||
} |
|
||||
|
|
||||
// ZMQ_SOCKS_PROXY: NOT DOCUMENTED
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented41 with ZeroMQ version < 4.1
|
|
||||
//
|
|
||||
func (soc *Socket) GetSocksProxy() (string, error) { |
|
||||
if minor < 1 { |
|
||||
return "", ErrorNotImplemented41 |
|
||||
} |
|
||||
return soc.getString(C.ZMQ_SOCKS_PROXY, 1024) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_XPUB_NODROP: SET ONLY? (not documented)
|
|
||||
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// New in ZeroMQ 4.2.0
|
|
||||
//
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// + : yes
|
|
||||
// o : setsockopt only
|
|
||||
// implemented documented test
|
|
||||
// ZMQ_BLOCKY
|
|
||||
// ZMQ_XPUB_MANUAL o
|
|
||||
// ZMQ_XPUB_WELCOME_MSG o
|
|
||||
// ZMQ_STREAM_NOTIFY o
|
|
||||
// ZMQ_INVERT_MATCHING + +
|
|
||||
// ZMQ_HEARTBEAT_IVL o
|
|
||||
// ZMQ_HEARTBEAT_TTL o
|
|
||||
// ZMQ_HEARTBEAT_TIMEOUT o
|
|
||||
// ZMQ_XPUB_VERBOSER o
|
|
||||
// ZMQ_CONNECT_TIMEOUT + +
|
|
||||
// ZMQ_TCP_MAXRT + +
|
|
||||
// ZMQ_THREAD_SAFE + +
|
|
||||
// ZMQ_MULTICAST_MAXTPDU + +
|
|
||||
// ZMQ_VMCI_BUFFER_SIZE + +
|
|
||||
// ZMQ_VMCI_BUFFER_MIN_SIZE + +
|
|
||||
// ZMQ_VMCI_BUFFER_MAX_SIZE + +
|
|
||||
// ZMQ_VMCI_CONNECT_TIMEOUT + +
|
|
||||
// ZMQ_USE_FD + +
|
|
||||
//
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
// ZMQ_BLOCKY doesn't look like a socket option
|
|
||||
|
|
||||
// ZMQ_INVERT_MATCHING: Retrieve inverted filtering status
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-getsockopt#toc18
|
|
||||
func (soc *Socket) GetInvertMatching() (int, error) { |
|
||||
if minor < 2 { |
|
||||
return 0, ErrorNotImplemented42 |
|
||||
} |
|
||||
return soc.getInt(C.ZMQ_INVERT_MATCHING) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_CONNECT_TIMEOUT: Retrieve connect() timeout
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-getsockopt#toc5
|
|
||||
func (soc *Socket) GetConnectTimeout() (time.Duration, error) { |
|
||||
if minor < 2 { |
|
||||
return time.Duration(0), ErrorNotImplemented42 |
|
||||
} |
|
||||
v, err := soc.getInt(C.ZMQ_CONNECT_TIMEOUT) |
|
||||
return time.Duration(v) * time.Millisecond, err |
|
||||
} |
|
||||
|
|
||||
// ZMQ_TCP_MAXRT: Retrieve Max TCP Retransmit Timeout
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-getsockopt#toc44
|
|
||||
func (soc *Socket) GetTcpMaxrt() (time.Duration, error) { |
|
||||
if minor < 2 { |
|
||||
return time.Duration(0), ErrorNotImplemented42 |
|
||||
} |
|
||||
v, err := soc.getInt(C.ZMQ_TCP_MAXRT) |
|
||||
return time.Duration(v) * time.Millisecond, err |
|
||||
} |
|
||||
|
|
||||
// ZMQ_THREAD_SAFE: Retrieve socket thread safety
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-getsockopt#toc45
|
|
||||
func (soc *Socket) GetThreadSafe() (bool, error) { |
|
||||
if minor < 2 { |
|
||||
return false, ErrorNotImplemented42 |
|
||||
} |
|
||||
v, err := soc.getInt(C.ZMQ_THREAD_SAFE) |
|
||||
return v != 0, err |
|
||||
} |
|
||||
|
|
||||
// ZMQ_MULTICAST_MAXTPDU: Maximum transport data unit size for multicast packets
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-getsockopt#toc26
|
|
||||
func (soc *Socket) GetMulticastMaxtpdu() (int, error) { |
|
||||
if minor < 2 { |
|
||||
return 0, ErrorNotImplemented42 |
|
||||
} |
|
||||
return soc.getInt(C.ZMQ_MULTICAST_MAXTPDU) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_VMCI_BUFFER_SIZE: Retrieve buffer size of the VMCI socket
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-getsockopt#toc49
|
|
||||
func (soc *Socket) GetVmciBufferSize() (uint64, error) { |
|
||||
if minor < 2 { |
|
||||
return 0, ErrorNotImplemented42 |
|
||||
} |
|
||||
return soc.getUInt64(C.ZMQ_VMCI_BUFFER_SIZE) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_VMCI_BUFFER_MIN_SIZE: Retrieve min buffer size of the VMCI socket
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-getsockopt#toc50
|
|
||||
func (soc *Socket) GetVmciBufferMinSize() (uint64, error) { |
|
||||
if minor < 2 { |
|
||||
return 0, ErrorNotImplemented42 |
|
||||
} |
|
||||
return soc.getUInt64(C.ZMQ_VMCI_BUFFER_MIN_SIZE) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_VMCI_BUFFER_MAX_SIZE: Retrieve max buffer size of the VMCI socket
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-getsockopt#toc51
|
|
||||
func (soc *Socket) GetVmciBufferMaxSize() (uint64, error) { |
|
||||
if minor < 2 { |
|
||||
return 0, ErrorNotImplemented42 |
|
||||
} |
|
||||
return soc.getUInt64(C.ZMQ_VMCI_BUFFER_MAX_SIZE) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_VMCI_CONNECT_TIMEOUT: Retrieve connection timeout of the VMCI socket
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-getsockopt#toc52
|
|
||||
func (soc *Socket) GetVmciConnectTimeout() (time.Duration, error) { |
|
||||
if minor < 2 { |
|
||||
return time.Duration(0), ErrorNotImplemented42 |
|
||||
} |
|
||||
v, err := soc.getInt(C.ZMQ_VMCI_CONNECT_TIMEOUT) |
|
||||
return time.Duration(v) * time.Millisecond, err |
|
||||
} |
|
||||
|
|
||||
// ZMQ_USE_FD: Retrieve the pre-allocated socket file descriptor
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-getsockopt#toc29
|
|
||||
func (soc *Socket) Getusefd() (int, error) { |
|
||||
if minor < 2 { |
|
||||
return 0, ErrorNotImplemented42 |
|
||||
} |
|
||||
return soc.getInt(C.ZMQ_USE_FD) |
|
||||
} |
|
@ -1,15 +0,0 @@ |
|||||
// +build !windows
|
|
||||
|
|
||||
package zmq4 |
|
||||
|
|
||||
/* |
|
||||
#include <zmq.h> |
|
||||
*/ |
|
||||
import "C" |
|
||||
|
|
||||
// ZMQ_FD: Retrieve file descriptor associated with the socket
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-getsockopt#toc9
|
|
||||
func (soc *Socket) GetFd() (int, error) { |
|
||||
return soc.getInt(C.ZMQ_FD) |
|
||||
} |
|
@ -1,26 +0,0 @@ |
|||||
// +build windows
|
|
||||
|
|
||||
package zmq4 |
|
||||
|
|
||||
/* |
|
||||
#include <zmq.h> |
|
||||
*/ |
|
||||
import "C" |
|
||||
|
|
||||
import ( |
|
||||
"unsafe" |
|
||||
) |
|
||||
|
|
||||
/* |
|
||||
ZMQ_FD: Retrieve file descriptor associated with the socket |
|
||||
|
|
||||
See: http://api.zeromq.org/4-1:zmq-getsockopt#toc9
|
|
||||
*/ |
|
||||
func (soc *Socket) GetFd() (uintptr, error) { |
|
||||
value := C.SOCKET(0) |
|
||||
size := C.size_t(unsafe.Sizeof(value)) |
|
||||
if i, err := C.zmq_getsockopt(soc.soc, C.ZMQ_FD, unsafe.Pointer(&value), &size); i != 0 { |
|
||||
return uintptr(0), errget(err) |
|
||||
} |
|
||||
return uintptr(value), nil |
|
||||
} |
|
@ -1,800 +0,0 @@ |
|||||
package zmq4 |
|
||||
|
|
||||
/* |
|
||||
#include <zmq.h> |
|
||||
#include <stdint.h> |
|
||||
#include <stdlib.h> |
|
||||
#include "zmq4.h" |
|
||||
*/ |
|
||||
import "C" |
|
||||
|
|
||||
import ( |
|
||||
"time" |
|
||||
"unsafe" |
|
||||
) |
|
||||
|
|
||||
func (soc *Socket) setString(opt C.int, s string) error { |
|
||||
if !soc.opened { |
|
||||
return ErrorSocketClosed |
|
||||
} |
|
||||
cs := C.CString(s) |
|
||||
defer C.free(unsafe.Pointer(cs)) |
|
||||
if i, err := C.zmq_setsockopt(soc.soc, opt, unsafe.Pointer(cs), C.size_t(len(s))); i != 0 { |
|
||||
return errget(err) |
|
||||
} |
|
||||
return nil |
|
||||
} |
|
||||
|
|
||||
func (soc *Socket) setNullString(opt C.int) error { |
|
||||
if !soc.opened { |
|
||||
return ErrorSocketClosed |
|
||||
} |
|
||||
if i, err := C.zmq_setsockopt(soc.soc, opt, nil, 0); i != 0 { |
|
||||
return errget(err) |
|
||||
} |
|
||||
return nil |
|
||||
} |
|
||||
|
|
||||
func (soc *Socket) setInt(opt C.int, value int) error { |
|
||||
if !soc.opened { |
|
||||
return ErrorSocketClosed |
|
||||
} |
|
||||
val := C.int(value) |
|
||||
if i, err := C.zmq_setsockopt(soc.soc, opt, unsafe.Pointer(&val), C.size_t(unsafe.Sizeof(val))); i != 0 { |
|
||||
return errget(err) |
|
||||
} |
|
||||
return nil |
|
||||
} |
|
||||
|
|
||||
func (soc *Socket) setInt64(opt C.int, value int64) error { |
|
||||
if !soc.opened { |
|
||||
return ErrorSocketClosed |
|
||||
} |
|
||||
val := C.int64_t(value) |
|
||||
if i, err := C.zmq_setsockopt(soc.soc, opt, unsafe.Pointer(&val), C.size_t(unsafe.Sizeof(val))); i != 0 { |
|
||||
return errget(err) |
|
||||
} |
|
||||
return nil |
|
||||
} |
|
||||
|
|
||||
func (soc *Socket) setUInt64(opt C.int, value uint64) error { |
|
||||
if !soc.opened { |
|
||||
return ErrorSocketClosed |
|
||||
} |
|
||||
val := C.uint64_t(value) |
|
||||
if i, err := C.zmq_setsockopt(soc.soc, opt, unsafe.Pointer(&val), C.size_t(unsafe.Sizeof(val))); i != 0 { |
|
||||
return errget(err) |
|
||||
} |
|
||||
return nil |
|
||||
} |
|
||||
|
|
||||
// ZMQ_SNDHWM: Set high water mark for outbound messages
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc39
|
|
||||
func (soc *Socket) SetSndhwm(value int) error { |
|
||||
return soc.setInt(C.ZMQ_SNDHWM, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_RCVHWM: Set high water mark for inbound messages
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc28
|
|
||||
func (soc *Socket) SetRcvhwm(value int) error { |
|
||||
return soc.setInt(C.ZMQ_RCVHWM, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_AFFINITY: Set I/O thread affinity
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc3
|
|
||||
func (soc *Socket) SetAffinity(value uint64) error { |
|
||||
return soc.setUInt64(C.ZMQ_AFFINITY, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_SUBSCRIBE: Establish message filter
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc41
|
|
||||
func (soc *Socket) SetSubscribe(filter string) error { |
|
||||
return soc.setString(C.ZMQ_SUBSCRIBE, filter) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_UNSUBSCRIBE: Remove message filter
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc47
|
|
||||
func (soc *Socket) SetUnsubscribe(filter string) error { |
|
||||
return soc.setString(C.ZMQ_UNSUBSCRIBE, filter) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_IDENTITY: Set socket identity
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc16
|
|
||||
func (soc *Socket) SetIdentity(value string) error { |
|
||||
return soc.setString(C.ZMQ_IDENTITY, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_RATE: Set multicast data rate
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc26
|
|
||||
func (soc *Socket) SetRate(value int) error { |
|
||||
return soc.setInt(C.ZMQ_RATE, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_RECOVERY_IVL: Set multicast recovery interval
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc32
|
|
||||
func (soc *Socket) SetRecoveryIvl(value time.Duration) error { |
|
||||
val := int(value / time.Millisecond) |
|
||||
return soc.setInt(C.ZMQ_RECOVERY_IVL, val) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_SNDBUF: Set kernel transmit buffer size
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc38
|
|
||||
func (soc *Socket) SetSndbuf(value int) error { |
|
||||
return soc.setInt(C.ZMQ_SNDBUF, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_RCVBUF: Set kernel receive buffer size
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc27
|
|
||||
func (soc *Socket) SetRcvbuf(value int) error { |
|
||||
return soc.setInt(C.ZMQ_RCVBUF, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_LINGER: Set linger period for socket shutdown
|
|
||||
//
|
|
||||
// For infinite, use -1
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc19
|
|
||||
func (soc *Socket) SetLinger(value time.Duration) error { |
|
||||
val := int(value / time.Millisecond) |
|
||||
if value == -1 { |
|
||||
val = -1 |
|
||||
} |
|
||||
return soc.setInt(C.ZMQ_LINGER, val) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_RECONNECT_IVL: Set reconnection interval
|
|
||||
//
|
|
||||
// For no reconnection, use -1
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc30
|
|
||||
func (soc *Socket) SetReconnectIvl(value time.Duration) error { |
|
||||
val := int(value / time.Millisecond) |
|
||||
if value == -1 { |
|
||||
val = -1 |
|
||||
} |
|
||||
return soc.setInt(C.ZMQ_RECONNECT_IVL, val) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_RECONNECT_IVL_MAX: Set maximum reconnection interval
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc31
|
|
||||
func (soc *Socket) SetReconnectIvlMax(value time.Duration) error { |
|
||||
val := int(value / time.Millisecond) |
|
||||
return soc.setInt(C.ZMQ_RECONNECT_IVL_MAX, val) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_BACKLOG: Set maximum length of the queue of outstanding connections
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc4
|
|
||||
func (soc *Socket) SetBacklog(value int) error { |
|
||||
return soc.setInt(C.ZMQ_BACKLOG, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_MAXMSGSIZE: Maximum acceptable inbound message size
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc20
|
|
||||
func (soc *Socket) SetMaxmsgsize(value int64) error { |
|
||||
return soc.setInt64(C.ZMQ_MAXMSGSIZE, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_MULTICAST_HOPS: Maximum network hops for multicast packets
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc21
|
|
||||
func (soc *Socket) SetMulticastHops(value int) error { |
|
||||
return soc.setInt(C.ZMQ_MULTICAST_HOPS, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_RCVTIMEO: Maximum time before a recv operation returns with EAGAIN
|
|
||||
//
|
|
||||
// For infinite, use -1
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc29
|
|
||||
func (soc *Socket) SetRcvtimeo(value time.Duration) error { |
|
||||
val := int(value / time.Millisecond) |
|
||||
if value == -1 { |
|
||||
val = -1 |
|
||||
} |
|
||||
return soc.setInt(C.ZMQ_RCVTIMEO, val) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_SNDTIMEO: Maximum time before a send operation returns with EAGAIN
|
|
||||
//
|
|
||||
// For infinite, use -1
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc40
|
|
||||
func (soc *Socket) SetSndtimeo(value time.Duration) error { |
|
||||
val := int(value / time.Millisecond) |
|
||||
if value == -1 { |
|
||||
val = -1 |
|
||||
} |
|
||||
return soc.setInt(C.ZMQ_SNDTIMEO, val) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_IPV6: Enable IPv6 on socket
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc18
|
|
||||
func (soc *Socket) SetIpv6(value bool) error { |
|
||||
val := 0 |
|
||||
if value { |
|
||||
val = 1 |
|
||||
} |
|
||||
return soc.setInt(C.ZMQ_IPV6, val) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_IMMEDIATE: Queue messages only to completed connections
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc17
|
|
||||
func (soc *Socket) SetImmediate(value bool) error { |
|
||||
val := 0 |
|
||||
if value { |
|
||||
val = 1 |
|
||||
} |
|
||||
return soc.setInt(C.ZMQ_IMMEDIATE, val) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_ROUTER_MANDATORY: accept only routable messages on ROUTER sockets
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc36
|
|
||||
func (soc *Socket) SetRouterMandatory(value int) error { |
|
||||
return soc.setInt(C.ZMQ_ROUTER_MANDATORY, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_ROUTER_RAW: switch ROUTER socket to raw mode
|
|
||||
//
|
|
||||
// This option is deprecated since ZeroMQ version 4.1, please use ZMQ_STREAM sockets instead.
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc37
|
|
||||
func (soc *Socket) SetRouterRaw(value int) error { |
|
||||
return soc.setInt(C.ZMQ_ROUTER_RAW, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_PROBE_ROUTER: bootstrap connections to ROUTER sockets
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc25
|
|
||||
func (soc *Socket) SetProbeRouter(value int) error { |
|
||||
return soc.setInt(C.ZMQ_PROBE_ROUTER, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_XPUB_VERBOSE: provide all subscription messages on XPUB sockets
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc48
|
|
||||
func (soc *Socket) SetXpubVerbose(value int) error { |
|
||||
return soc.setInt(C.ZMQ_XPUB_VERBOSE, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_REQ_CORRELATE: match replies with requests
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc33
|
|
||||
func (soc *Socket) SetReqCorrelate(value int) error { |
|
||||
return soc.setInt(C.ZMQ_REQ_CORRELATE, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_REQ_RELAXED: relax strict alternation between request and reply
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc34
|
|
||||
func (soc *Socket) SetReqRelaxed(value int) error { |
|
||||
return soc.setInt(C.ZMQ_REQ_RELAXED, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_TCP_KEEPALIVE: Override SO_KEEPALIVE socket option
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc42
|
|
||||
func (soc *Socket) SetTcpKeepalive(value int) error { |
|
||||
return soc.setInt(C.ZMQ_TCP_KEEPALIVE, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_TCP_KEEPALIVE_IDLE: Override TCP_KEEPCNT(or TCP_KEEPALIVE on some OS)
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc44
|
|
||||
func (soc *Socket) SetTcpKeepaliveIdle(value int) error { |
|
||||
return soc.setInt(C.ZMQ_TCP_KEEPALIVE_IDLE, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_TCP_KEEPALIVE_CNT: Override TCP_KEEPCNT socket option
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc43
|
|
||||
func (soc *Socket) SetTcpKeepaliveCnt(value int) error { |
|
||||
return soc.setInt(C.ZMQ_TCP_KEEPALIVE_CNT, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_TCP_KEEPALIVE_INTVL: Override TCP_KEEPINTVL socket option
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc45
|
|
||||
func (soc *Socket) SetTcpKeepaliveIntvl(value int) error { |
|
||||
return soc.setInt(C.ZMQ_TCP_KEEPALIVE_INTVL, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_TCP_ACCEPT_FILTER: Assign filters to allow new TCP connections
|
|
||||
//
|
|
||||
// This option is deprecated since ZeroMQ version 4.1, please use authentication via
|
|
||||
// the ZAP API and IP address whitelisting / blacklisting.
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc50
|
|
||||
func (soc *Socket) SetTcpAcceptFilter(filter string) error { |
|
||||
if len(filter) == 0 { |
|
||||
return soc.setNullString(C.ZMQ_TCP_ACCEPT_FILTER) |
|
||||
} |
|
||||
return soc.setString(C.ZMQ_TCP_ACCEPT_FILTER, filter) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_PLAIN_SERVER: Set PLAIN server role
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc23
|
|
||||
func (soc *Socket) SetPlainServer(value int) error { |
|
||||
return soc.setInt(C.ZMQ_PLAIN_SERVER, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_PLAIN_USERNAME: Set PLAIN security username
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc24
|
|
||||
func (soc *Socket) SetPlainUsername(username string) error { |
|
||||
if len(username) == 0 { |
|
||||
return soc.setNullString(C.ZMQ_PLAIN_USERNAME) |
|
||||
} |
|
||||
return soc.setString(C.ZMQ_PLAIN_USERNAME, username) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_PLAIN_PASSWORD: Set PLAIN security password
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc22
|
|
||||
func (soc *Socket) SetPlainPassword(password string) error { |
|
||||
if len(password) == 0 { |
|
||||
return soc.setNullString(C.ZMQ_PLAIN_PASSWORD) |
|
||||
} |
|
||||
return soc.setString(C.ZMQ_PLAIN_PASSWORD, password) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_CURVE_SERVER: Set CURVE server role
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc9
|
|
||||
func (soc *Socket) SetCurveServer(value int) error { |
|
||||
return soc.setInt(C.ZMQ_CURVE_SERVER, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_CURVE_PUBLICKEY: Set CURVE public key
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc7
|
|
||||
func (soc *Socket) SetCurvePublickey(key string) error { |
|
||||
return soc.setString(C.ZMQ_CURVE_PUBLICKEY, key) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_CURVE_SECRETKEY: Set CURVE secret key
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc8
|
|
||||
func (soc *Socket) SetCurveSecretkey(key string) error { |
|
||||
return soc.setString(C.ZMQ_CURVE_SECRETKEY, key) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_CURVE_SERVERKEY: Set CURVE server key
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc10
|
|
||||
func (soc *Socket) SetCurveServerkey(key string) error { |
|
||||
return soc.setString(C.ZMQ_CURVE_SERVERKEY, key) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_ZAP_DOMAIN: Set RFC 27 authentication domain
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc49
|
|
||||
func (soc *Socket) SetZapDomain(domain string) error { |
|
||||
return soc.setString(C.ZMQ_ZAP_DOMAIN, domain) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_CONFLATE: Keep only last message
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc6
|
|
||||
func (soc *Socket) SetConflate(value bool) error { |
|
||||
val := 0 |
|
||||
if value { |
|
||||
val = 1 |
|
||||
} |
|
||||
return soc.setInt(C.ZMQ_CONFLATE, val) |
|
||||
} |
|
||||
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// New in ZeroMQ 4.1.0
|
|
||||
//
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// + : yes
|
|
||||
// D : deprecated
|
|
||||
// implemented documented test
|
|
||||
// ZMQ_ROUTER_HANDOVER + +
|
|
||||
// ZMQ_TOS + +
|
|
||||
// ZMQ_IPC_FILTER_PID D
|
|
||||
// ZMQ_IPC_FILTER_UID D
|
|
||||
// ZMQ_IPC_FILTER_GID D
|
|
||||
// ZMQ_CONNECT_RID + +
|
|
||||
// ZMQ_GSSAPI_SERVER + +
|
|
||||
// ZMQ_GSSAPI_PRINCIPAL + +
|
|
||||
// ZMQ_GSSAPI_SERVICE_PRINCIPAL + +
|
|
||||
// ZMQ_GSSAPI_PLAINTEXT + +
|
|
||||
// ZMQ_HANDSHAKE_IVL + +
|
|
||||
// ZMQ_SOCKS_PROXY +
|
|
||||
// ZMQ_XPUB_NODROP +
|
|
||||
//
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
// ZMQ_ROUTER_HANDOVER: handle duplicate client identities on ROUTER sockets
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented41 with ZeroMQ version < 4.1
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc35
|
|
||||
func (soc *Socket) SetRouterHandover(value bool) error { |
|
||||
if minor < 1 { |
|
||||
return ErrorNotImplemented41 |
|
||||
} |
|
||||
val := 0 |
|
||||
if value { |
|
||||
val = 1 |
|
||||
} |
|
||||
return soc.setInt(C.ZMQ_ROUTER_HANDOVER, val) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_TOS: Set the Type-of-Service on socket
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented41 with ZeroMQ version < 4.1
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc46
|
|
||||
func (soc *Socket) SetTos(value int) error { |
|
||||
if minor < 1 { |
|
||||
return ErrorNotImplemented41 |
|
||||
} |
|
||||
return soc.setInt(C.ZMQ_TOS, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_CONNECT_RID: Assign the next outbound connection id
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented41 with ZeroMQ version < 4.1
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc5
|
|
||||
func (soc *Socket) SetConnectRid(value string) error { |
|
||||
if minor < 1 { |
|
||||
return ErrorNotImplemented41 |
|
||||
} |
|
||||
if value == "" { |
|
||||
return soc.setNullString(C.ZMQ_CONNECT_RID) |
|
||||
} |
|
||||
return soc.setString(C.ZMQ_CONNECT_RID, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_GSSAPI_SERVER: Set GSSAPI server role
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented41 with ZeroMQ version < 4.1
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc13
|
|
||||
func (soc *Socket) SetGssapiServer(value bool) error { |
|
||||
if minor < 1 { |
|
||||
return ErrorNotImplemented41 |
|
||||
} |
|
||||
val := 0 |
|
||||
if value { |
|
||||
val = 1 |
|
||||
} |
|
||||
return soc.setInt(C.ZMQ_GSSAPI_SERVER, val) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_GSSAPI_PRINCIPAL: Set name of GSSAPI principal
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented41 with ZeroMQ version < 4.1
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc12
|
|
||||
func (soc *Socket) SetGssapiPrincipal(value string) error { |
|
||||
if minor < 1 { |
|
||||
return ErrorNotImplemented41 |
|
||||
} |
|
||||
return soc.setString(C.ZMQ_GSSAPI_PRINCIPAL, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_GSSAPI_SERVICE_PRINCIPAL: Set name of GSSAPI service principal
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented41 with ZeroMQ version < 4.1
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc14
|
|
||||
func (soc *Socket) SetGssapiServicePrincipal(value string) error { |
|
||||
if minor < 1 { |
|
||||
return ErrorNotImplemented41 |
|
||||
} |
|
||||
return soc.setString(C.ZMQ_GSSAPI_SERVICE_PRINCIPAL, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_GSSAPI_PLAINTEXT: Disable GSSAPI encryption
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented41 with ZeroMQ version < 4.1
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc11
|
|
||||
func (soc *Socket) SetGssapiPlaintext(value bool) error { |
|
||||
if minor < 1 { |
|
||||
return ErrorNotImplemented41 |
|
||||
} |
|
||||
val := 0 |
|
||||
if value { |
|
||||
val = 1 |
|
||||
} |
|
||||
return soc.setInt(C.ZMQ_GSSAPI_PLAINTEXT, val) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_HANDSHAKE_IVL: Set maximum handshake interval
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented41 with ZeroMQ version < 4.1
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-1:zmq-setsockopt#toc15
|
|
||||
func (soc *Socket) SetHandshakeIvl(value time.Duration) error { |
|
||||
if minor < 1 { |
|
||||
return ErrorNotImplemented41 |
|
||||
} |
|
||||
val := int(value / time.Millisecond) |
|
||||
return soc.setInt(C.ZMQ_HANDSHAKE_IVL, val) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_SOCKS_PROXY: NOT DOCUMENTED
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented41 with ZeroMQ version < 4.1
|
|
||||
func (soc *Socket) SetSocksProxy(value string) error { |
|
||||
if minor < 1 { |
|
||||
return ErrorNotImplemented41 |
|
||||
} |
|
||||
if value == "" { |
|
||||
return soc.setNullString(C.ZMQ_SOCKS_PROXY) |
|
||||
} |
|
||||
return soc.setString(C.ZMQ_SOCKS_PROXY, value) |
|
||||
} |
|
||||
|
|
||||
// Available since ZeroMQ 4.1, documented since ZeroMQ 4.2
|
|
||||
|
|
||||
// ZMQ_XPUB_NODROP: do not silently drop messages if SENDHWM is reached
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented41 with ZeroMQ version < 4.1
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-setsockopt#toc60
|
|
||||
func (soc *Socket) SetXpubNodrop(value bool) error { |
|
||||
if minor < 1 { |
|
||||
return ErrorNotImplemented41 |
|
||||
} |
|
||||
val := 0 |
|
||||
if value { |
|
||||
val = 1 |
|
||||
} |
|
||||
return soc.setInt(C.ZMQ_XPUB_NODROP, val) |
|
||||
} |
|
||||
|
|
||||
////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// New in ZeroMQ 4.2.0
|
|
||||
//
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// + : yes
|
|
||||
// o : getsockopt only
|
|
||||
// implemented documented test
|
|
||||
// ZMQ_BLOCKY
|
|
||||
// ZMQ_XPUB_MANUAL + +
|
|
||||
// ZMQ_XPUB_WELCOME_MSG + +
|
|
||||
// ZMQ_STREAM_NOTIFY + +
|
|
||||
// ZMQ_INVERT_MATCHING + +
|
|
||||
// ZMQ_HEARTBEAT_IVL + +
|
|
||||
// ZMQ_HEARTBEAT_TTL + +
|
|
||||
// ZMQ_HEARTBEAT_TIMEOUT + +
|
|
||||
// ZMQ_XPUB_VERBOSER + +
|
|
||||
// ZMQ_CONNECT_TIMEOUT + +
|
|
||||
// ZMQ_TCP_MAXRT + +
|
|
||||
// ZMQ_THREAD_SAFE o
|
|
||||
// ZMQ_MULTICAST_MAXTPDU + +
|
|
||||
// ZMQ_VMCI_BUFFER_SIZE + +
|
|
||||
// ZMQ_VMCI_BUFFER_MIN_SIZE + +
|
|
||||
// ZMQ_VMCI_BUFFER_MAX_SIZE + +
|
|
||||
// ZMQ_VMCI_CONNECT_TIMEOUT + +
|
|
||||
// ZMQ_USE_FD + +
|
|
||||
//
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
// ZMQ_XPUB_MANUAL: change the subscription handling to manual
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-setsockopt#toc59
|
|
||||
func (soc *Socket) SetXpubManual(value int) error { |
|
||||
if minor < 2 { |
|
||||
return ErrorNotImplemented42 |
|
||||
} |
|
||||
return soc.setInt(C.ZMQ_XPUB_MANUAL, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_XPUB_WELCOME_MSG: set welcome message that will be received by subscriber when connecting
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-setsockopt#toc61
|
|
||||
func (soc *Socket) SetXpubWelcomeMsg(value string) error { |
|
||||
if minor < 2 { |
|
||||
return ErrorNotImplemented42 |
|
||||
} |
|
||||
if value == "" { |
|
||||
return soc.setNullString(C.ZMQ_XPUB_WELCOME_MSG) |
|
||||
} |
|
||||
return soc.setString(C.ZMQ_XPUB_WELCOME_MSG, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_STREAM_NOTIFY: send connect and disconnect notifications
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-setsockopt#toc48
|
|
||||
func (soc *Socket) SetStreamNotify(value int) error { |
|
||||
if minor < 2 { |
|
||||
return ErrorNotImplemented42 |
|
||||
} |
|
||||
return soc.setInt(C.ZMQ_STREAM_NOTIFY, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_INVERT_MATCHING: Invert message filtering
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-setsockopt#toc22
|
|
||||
func (soc *Socket) SetInvertMatching(value int) error { |
|
||||
if minor < 2 { |
|
||||
return ErrorNotImplemented42 |
|
||||
} |
|
||||
return soc.setInt(C.ZMQ_INVERT_MATCHING, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_HEARTBEAT_IVL: Set interval between sending ZMTP heartbeats
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-setsockopt#toc17
|
|
||||
func (soc *Socket) SetHeartbeatIvl(value time.Duration) error { |
|
||||
if minor < 2 { |
|
||||
return ErrorNotImplemented42 |
|
||||
} |
|
||||
val := int(value / time.Millisecond) |
|
||||
return soc.setInt(C.ZMQ_HEARTBEAT_IVL, val) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_HEARTBEAT_TTL: Set the TTL value for ZMTP heartbeats
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-setsockopt#toc19
|
|
||||
func (soc *Socket) SetHeartbeatTtl(value time.Duration) error { |
|
||||
if minor < 2 { |
|
||||
return ErrorNotImplemented42 |
|
||||
} |
|
||||
val := int(value / time.Millisecond) |
|
||||
return soc.setInt(C.ZMQ_HEARTBEAT_TTL, val) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_HEARTBEAT_TIMEOUT: Set timeout for ZMTP heartbeats
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-setsockopt#toc18
|
|
||||
func (soc *Socket) SetHeartbeatTimeout(value time.Duration) error { |
|
||||
if minor < 2 { |
|
||||
return ErrorNotImplemented42 |
|
||||
} |
|
||||
val := int(value / time.Millisecond) |
|
||||
return soc.setInt(C.ZMQ_HEARTBEAT_TIMEOUT, val) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_XPUB_VERBOSER: pass subscribe and unsubscribe messages on XPUB socket
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-setsockopt#toc58
|
|
||||
func (soc *Socket) SetXpubVerboser(value int) error { |
|
||||
if minor < 2 { |
|
||||
return ErrorNotImplemented42 |
|
||||
} |
|
||||
return soc.setInt(C.ZMQ_XPUB_VERBOSER, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_CONNECT_TIMEOUT: Set connect() timeout
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-setsockopt#toc7
|
|
||||
func (soc *Socket) SetConnectTimeout(value time.Duration) error { |
|
||||
if minor < 2 { |
|
||||
return ErrorNotImplemented42 |
|
||||
} |
|
||||
val := int(value / time.Millisecond) |
|
||||
return soc.setInt(C.ZMQ_CONNECT_TIMEOUT, val) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_TCP_MAXRT: Set TCP Maximum Retransmit Timeout
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-setsockopt#toc54
|
|
||||
func (soc *Socket) SetTcpMaxrt(value time.Duration) error { |
|
||||
if minor < 2 { |
|
||||
return ErrorNotImplemented42 |
|
||||
} |
|
||||
val := int(value / time.Millisecond) |
|
||||
return soc.setInt(C.ZMQ_TCP_MAXRT, val) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_MULTICAST_MAXTPDU: Maximum transport data unit size for multicast packets
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-setsockopt#toc27
|
|
||||
func (soc *Socket) SetMulticastMaxtpdu(value int) error { |
|
||||
if minor < 2 { |
|
||||
return ErrorNotImplemented42 |
|
||||
} |
|
||||
return soc.setInt(C.ZMQ_MULTICAST_MAXTPDU, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_VMCI_BUFFER_SIZE: Set buffer size of the VMCI socket
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-setsockopt#toc68
|
|
||||
func (soc *Socket) SetVmciBufferSize(value uint64) error { |
|
||||
if minor < 2 { |
|
||||
return ErrorNotImplemented42 |
|
||||
} |
|
||||
return soc.setUInt64(C.ZMQ_VMCI_BUFFER_SIZE, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_VMCI_BUFFER_MIN_SIZE: Set min buffer size of the VMCI socket
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-setsockopt#toc69
|
|
||||
func (soc *Socket) SetVmciBufferMinSize(value uint64) error { |
|
||||
if minor < 2 { |
|
||||
return ErrorNotImplemented42 |
|
||||
} |
|
||||
return soc.setUInt64(C.ZMQ_VMCI_BUFFER_MIN_SIZE, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_VMCI_BUFFER_MAX_SIZE: Set max buffer size of the VMCI socket
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-setsockopt#toc70
|
|
||||
func (soc *Socket) SetVmciBufferMaxSize(value uint64) error { |
|
||||
if minor < 2 { |
|
||||
return ErrorNotImplemented42 |
|
||||
} |
|
||||
return soc.setUInt64(C.ZMQ_VMCI_BUFFER_MAX_SIZE, value) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_VMCI_CONNECT_TIMEOUT: Set connection timeout of the VMCI socket
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-setsockopt#toc71
|
|
||||
func (soc *Socket) SetVmciConnectTimeout(value time.Duration) error { |
|
||||
if minor < 2 { |
|
||||
return ErrorNotImplemented42 |
|
||||
} |
|
||||
val := int(value / time.Millisecond) |
|
||||
return soc.setInt(C.ZMQ_VMCI_CONNECT_TIMEOUT, val) |
|
||||
} |
|
||||
|
|
||||
// ZMQ_USE_FD: Set the pre-allocated socket file descriptor
|
|
||||
//
|
|
||||
// Returns ErrorNotImplemented42 with ZeroMQ version < 4.2
|
|
||||
//
|
|
||||
// See: http://api.zeromq.org/4-2:zmq-setsockopt#toc31
|
|
||||
func (soc *Socket) SetUseFd(value int) error { |
|
||||
if minor < 2 { |
|
||||
return ErrorNotImplemented42 |
|
||||
} |
|
||||
return soc.setInt(C.ZMQ_USE_FD, value) |
|
||||
} |
|
@ -1,206 +0,0 @@ |
|||||
package zmq4 |
|
||||
|
|
||||
import ( |
|
||||
"fmt" |
|
||||
) |
|
||||
|
|
||||
/* |
|
||||
Send multi-part message on socket. |
|
||||
|
|
||||
Any `[]string' or `[][]byte' is split into separate `string's or `[]byte's |
|
||||
|
|
||||
Any other part that isn't a `string' or `[]byte' is converted |
|
||||
to `string' with `fmt.Sprintf("%v", part)'. |
|
||||
|
|
||||
Returns total bytes sent. |
|
||||
*/ |
|
||||
func (soc *Socket) SendMessage(parts ...interface{}) (total int, err error) { |
|
||||
return soc.sendMessage(0, parts...) |
|
||||
} |
|
||||
|
|
||||
/* |
|
||||
Like SendMessage(), but adding the DONTWAIT flag. |
|
||||
*/ |
|
||||
func (soc *Socket) SendMessageDontwait(parts ...interface{}) (total int, err error) { |
|
||||
return soc.sendMessage(DONTWAIT, parts...) |
|
||||
} |
|
||||
|
|
||||
func (soc *Socket) sendMessage(dontwait Flag, parts ...interface{}) (total int, err error) { |
|
||||
|
|
||||
var last int |
|
||||
PARTS: |
|
||||
for last = len(parts) - 1; last >= 0; last-- { |
|
||||
switch t := parts[last].(type) { |
|
||||
case []string: |
|
||||
if len(t) > 0 { |
|
||||
break PARTS |
|
||||
} |
|
||||
case [][]byte: |
|
||||
if len(t) > 0 { |
|
||||
break PARTS |
|
||||
} |
|
||||
default: |
|
||||
break PARTS |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
opt := SNDMORE | dontwait |
|
||||
for i := 0; i <= last; i++ { |
|
||||
if i == last { |
|
||||
opt = dontwait |
|
||||
} |
|
||||
switch t := parts[i].(type) { |
|
||||
case []string: |
|
||||
opt = SNDMORE | dontwait |
|
||||
n := len(t) - 1 |
|
||||
for j, s := range t { |
|
||||
if j == n && i == last { |
|
||||
opt = dontwait |
|
||||
} |
|
||||
c, e := soc.Send(s, opt) |
|
||||
if e == nil { |
|
||||
total += c |
|
||||
} else { |
|
||||
return -1, e |
|
||||
} |
|
||||
} |
|
||||
case [][]byte: |
|
||||
opt = SNDMORE | dontwait |
|
||||
n := len(t) - 1 |
|
||||
for j, b := range t { |
|
||||
if j == n && i == last { |
|
||||
opt = dontwait |
|
||||
} |
|
||||
c, e := soc.SendBytes(b, opt) |
|
||||
if e == nil { |
|
||||
total += c |
|
||||
} else { |
|
||||
return -1, e |
|
||||
} |
|
||||
} |
|
||||
case string: |
|
||||
c, e := soc.Send(t, opt) |
|
||||
if e == nil { |
|
||||
total += c |
|
||||
} else { |
|
||||
return -1, e |
|
||||
} |
|
||||
case []byte: |
|
||||
c, e := soc.SendBytes(t, opt) |
|
||||
if e == nil { |
|
||||
total += c |
|
||||
} else { |
|
||||
return -1, e |
|
||||
} |
|
||||
default: |
|
||||
c, e := soc.Send(fmt.Sprintf("%v", t), opt) |
|
||||
if e == nil { |
|
||||
total += c |
|
||||
} else { |
|
||||
return -1, e |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
/* |
|
||||
Receive parts as message from socket. |
|
||||
|
|
||||
Returns last non-nil error code. |
|
||||
*/ |
|
||||
func (soc *Socket) RecvMessage(flags Flag) (msg []string, err error) { |
|
||||
msg = make([]string, 0) |
|
||||
for { |
|
||||
s, e := soc.Recv(flags) |
|
||||
if e == nil { |
|
||||
msg = append(msg, s) |
|
||||
} else { |
|
||||
return msg[0:0], e |
|
||||
} |
|
||||
more, e := soc.GetRcvmore() |
|
||||
if e == nil { |
|
||||
if !more { |
|
||||
break |
|
||||
} |
|
||||
} else { |
|
||||
return msg[0:0], e |
|
||||
} |
|
||||
} |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
/* |
|
||||
Receive parts as message from socket. |
|
||||
|
|
||||
Returns last non-nil error code. |
|
||||
*/ |
|
||||
func (soc *Socket) RecvMessageBytes(flags Flag) (msg [][]byte, err error) { |
|
||||
msg = make([][]byte, 0) |
|
||||
for { |
|
||||
b, e := soc.RecvBytes(flags) |
|
||||
if e == nil { |
|
||||
msg = append(msg, b) |
|
||||
} else { |
|
||||
return msg[0:0], e |
|
||||
} |
|
||||
more, e := soc.GetRcvmore() |
|
||||
if e == nil { |
|
||||
if !more { |
|
||||
break |
|
||||
} |
|
||||
} else { |
|
||||
return msg[0:0], e |
|
||||
} |
|
||||
} |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
/* |
|
||||
Receive parts as message from socket, including metadata. |
|
||||
|
|
||||
Metadata is picked from the first message part. |
|
||||
|
|
||||
For details about metadata, see RecvWithMetadata(). |
|
||||
|
|
||||
Returns last non-nil error code. |
|
||||
*/ |
|
||||
func (soc *Socket) RecvMessageWithMetadata(flags Flag, properties ...string) (msg []string, metadata map[string]string, err error) { |
|
||||
b, p, err := soc.RecvMessageBytesWithMetadata(flags, properties...) |
|
||||
m := make([]string, len(b)) |
|
||||
for i, bt := range b { |
|
||||
m[i] = string(bt) |
|
||||
} |
|
||||
return m, p, err |
|
||||
} |
|
||||
|
|
||||
/* |
|
||||
Receive parts as message from socket, including metadata. |
|
||||
|
|
||||
Metadata is picked from the first message part. |
|
||||
|
|
||||
For details about metadata, see RecvBytesWithMetadata(). |
|
||||
|
|
||||
Returns last non-nil error code. |
|
||||
*/ |
|
||||
func (soc *Socket) RecvMessageBytesWithMetadata(flags Flag, properties ...string) (msg [][]byte, metadata map[string]string, err error) { |
|
||||
bb := make([][]byte, 0) |
|
||||
b, p, err := soc.RecvBytesWithMetadata(flags, properties...) |
|
||||
if err != nil { |
|
||||
return bb, p, err |
|
||||
} |
|
||||
for { |
|
||||
bb = append(bb, b) |
|
||||
|
|
||||
var more bool |
|
||||
more, err = soc.GetRcvmore() |
|
||||
if err != nil || !more { |
|
||||
break |
|
||||
} |
|
||||
b, err = soc.RecvBytes(flags) |
|
||||
if err != nil { |
|
||||
break |
|
||||
} |
|
||||
} |
|
||||
return bb, p, err |
|
||||
} |
|
File diff suppressed because it is too large
@ -1,62 +0,0 @@ |
|||||
#if ZMQ_VERSION_MAJOR != 4 |
|
||||
|
|
||||
#error "You need ZeroMQ version 4 to build this" |
|
||||
|
|
||||
#endif |
|
||||
|
|
||||
#if ZMQ_VERSION_MINOR < 1 |
|
||||
|
|
||||
#define ZMQ_CONNECT_RID -1 |
|
||||
#define ZMQ_GSSAPI -1 |
|
||||
#define ZMQ_GSSAPI_PLAINTEXT -1 |
|
||||
#define ZMQ_GSSAPI_PRINCIPAL -1 |
|
||||
#define ZMQ_GSSAPI_SERVER -1 |
|
||||
#define ZMQ_GSSAPI_SERVICE_PRINCIPAL -1 |
|
||||
#define ZMQ_HANDSHAKE_IVL -1 |
|
||||
#define ZMQ_IPC_FILTER_GID -1 |
|
||||
#define ZMQ_IPC_FILTER_PID -1 |
|
||||
#define ZMQ_IPC_FILTER_UID -1 |
|
||||
#define ZMQ_ROUTER_HANDOVER -1 |
|
||||
#define ZMQ_SOCKS_PROXY -1 |
|
||||
#define ZMQ_THREAD_PRIORITY -1 |
|
||||
#define ZMQ_THREAD_SCHED_POLICY -1 |
|
||||
#define ZMQ_TOS -1 |
|
||||
#define ZMQ_XPUB_NODROP -1 |
|
||||
|
|
||||
#endif |
|
||||
|
|
||||
#if ZMQ_VERSION_MINOR < 2 |
|
||||
|
|
||||
#define ZMQ_MAX_MSGSZ -1 |
|
||||
|
|
||||
#define ZMQ_BLOCKY -1 |
|
||||
#define ZMQ_XPUB_MANUAL -1 |
|
||||
#define ZMQ_XPUB_WELCOME_MSG -1 |
|
||||
#define ZMQ_STREAM_NOTIFY -1 |
|
||||
#define ZMQ_INVERT_MATCHING -1 |
|
||||
#define ZMQ_HEARTBEAT_IVL -1 |
|
||||
#define ZMQ_HEARTBEAT_TTL -1 |
|
||||
#define ZMQ_HEARTBEAT_TIMEOUT -1 |
|
||||
#define ZMQ_XPUB_VERBOSER -1 |
|
||||
#define ZMQ_CONNECT_TIMEOUT -1 |
|
||||
#define ZMQ_TCP_MAXRT -1 |
|
||||
#define ZMQ_THREAD_SAFE -1 |
|
||||
#define ZMQ_MULTICAST_MAXTPDU -1 |
|
||||
#define ZMQ_VMCI_BUFFER_SIZE -1 |
|
||||
#define ZMQ_VMCI_BUFFER_MIN_SIZE -1 |
|
||||
#define ZMQ_VMCI_BUFFER_MAX_SIZE -1 |
|
||||
#define ZMQ_VMCI_CONNECT_TIMEOUT -1 |
|
||||
#define ZMQ_USE_FD -1 |
|
||||
|
|
||||
#define ZMQ_GROUP_MAX_LENGTH -1 |
|
||||
|
|
||||
#define ZMQ_POLLPRI -1 |
|
||||
|
|
||||
#endif |
|
||||
|
|
||||
#ifndef ZMQ_ROUTING_ID |
|
||||
#define ZMQ_ROUTING_ID ZMQ_IDENTITY |
|
||||
#endif |
|
||||
#ifndef ZMQ_CONNECT_ROUTING_ID |
|
||||
#define ZMQ_CONNECT_ROUTING_ID ZMQ_CONNECT_RID |
|
||||
#endif |
|
Loading…
Reference in new issue