Compare commits

...

6 Commits

Author SHA1 Message Date
dave ec618653e6 remote control mode 2021-05-25 21:45:23 -07:00
dave 56db821e89 vendor deps 2021-05-20 18:09:29 -07:00
dave 54faf24046 zmq and refactor 2021-05-20 18:07:24 -07:00
dave 6e53f75326 cleanup, make sane 2021-05-20 10:30:34 -07:00
dave 202047b6c2 friends, load nicks from file, op mode 2021-05-16 22:00:21 -07:00
dave ac77aad4bc tweaks for running very many copies 2020-11-18 13:24:28 -08:00
55 changed files with 7231 additions and 56 deletions

1
.dockerignore Normal file
View File

@ -0,0 +1 @@
/swarm

View File

@ -1,3 +1,25 @@
FROM scratch
COPY swarm /
FROM ubuntu:bionic AS builder
RUN set -x && \
apt-get update && \
apt-get install -y wget libczmq4 libczmq-dev libsodium-dev libsodium23 pkg-config && \
wget -qO- https://golang.org/dl/go1.16.4.linux-amd64.tar.gz | tar -C /usr/local -xzf- && \
rm -vrf /var/lib/apt/lists/*
ADD . /tmp/code
RUN export PATH=$PATH:/usr/local/go/bin && \
cd /tmp/code && \
go build -o swarm cmd/swarm/main.go
FROM ubuntu:bionic
RUN set -x && \
apt-get update && \
apt-get install -y libczmq4 libsodium23 && \
rm -vrf /var/lib/apt/lists/*
COPY --from=builder /tmp/code/swarm /swarm
USER nobody
ENTRYPOINT ["/swarm"]

View File

@ -1,4 +1,6 @@
BUILDVARS := CGO_ENABLED=0
BUILDVARS :=
#CGO_ENABLED=0
TAG := latest
.PHONY: swarm
swarm:
@ -13,5 +15,9 @@ clean:
rm -vf swarm
.PHONY: image
image: linux
docker build -t dockermirror:5000/dpedu/antiroachswarm .
image:
docker build -t dockermirror:5000/dpedu/antiroachswarm:$(TAG) .
.PHONY: push
push: image
docker push dockermirror:5000/dpedu/antiroachswarm:$(TAG)

File diff suppressed because one or more lines are too long

9
go.mod Normal file
View File

@ -0,0 +1,9 @@
module git.davepedu.com/dave/antiroachlol
go 1.16
require (
golang.org/x/net v0.0.0-20210510120150-4163338589ed
gopkg.in/irc.v3 v3.1.4
gopkg.in/zeromq/goczmq.v4 v4.1.0
)

22
go.sum Normal file
View File

@ -0,0 +1,22 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
golang.org/x/net v0.0.0-20210510120150-4163338589ed h1:p9UgmWI9wKpfYmgaV/IZKGdXc5qEK45tDwwwDyjS26I=
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/irc.v3 v3.1.4 h1:DYGMRFbtseXEh+NadmMUFzMraqyuUj4I3iWYFEzDZPc=
gopkg.in/irc.v3 v3.1.4/go.mod h1:shO2gz8+PVeS+4E6GAny88Z0YVVQSxQghdrMVGQsR9s=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/zeromq/goczmq.v4 v4.1.0 h1:CE+FE81mGVs2aSlnbfLuS1oAwdcVywyMM2AC1g33imI=
gopkg.in/zeromq/goczmq.v4 v4.1.0/go.mod h1:h4IlfePEYMpFdywGr5gAwKhBBj+hiBl/nF4VoSE4k+0=

3
vendor/golang.org/x/net/AUTHORS generated vendored Normal file
View File

@ -0,0 +1,3 @@
# This source code refers to The Go Authors for copyright purposes.
# The master list of authors is in the main Go distribution,
# visible at http://tip.golang.org/AUTHORS.

3
vendor/golang.org/x/net/CONTRIBUTORS generated vendored Normal file
View File

@ -0,0 +1,3 @@
# This source code was written by the Go contributors.
# The master list of contributors is in the main Go distribution,
# visible at http://tip.golang.org/CONTRIBUTORS.

27
vendor/golang.org/x/net/LICENSE generated vendored Normal file
View File

@ -0,0 +1,27 @@
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* 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.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
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
OWNER 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.

22
vendor/golang.org/x/net/PATENTS generated vendored Normal file
View File

@ -0,0 +1,22 @@
Additional IP Rights Grant (Patents)
"This implementation" means the copyrightable works distributed by
Google as part of the Go project.
Google hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable (except as stated in this section)
patent license to make, have made, use, offer to sell, sell, import,
transfer and otherwise run, modify and propagate the contents of this
implementation of Go, where such license applies only to those patent
claims, both currently owned or controlled by Google and acquired in
the future, licensable by Google that are necessarily infringed by this
implementation of Go. This grant does not include claims that would be
infringed only as a consequence of further modification of this
implementation. If you or your agent or exclusive licensee institute or
order or agree to the institution of patent litigation against any
entity (including a cross-claim or counterclaim in a lawsuit) alleging
that this implementation of Go or any code incorporated within this
implementation of Go constitutes direct or contributory patent
infringement, or inducement of patent infringement, then any patent
rights granted to you under this License for this implementation of Go
shall terminate as of the date such litigation is filed.

168
vendor/golang.org/x/net/internal/socks/client.go generated vendored Normal file
View File

@ -0,0 +1,168 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package socks
import (
"context"
"errors"
"io"
"net"
"strconv"
"time"
)
var (
noDeadline = time.Time{}
aLongTimeAgo = time.Unix(1, 0)
)
func (d *Dialer) connect(ctx context.Context, c net.Conn, address string) (_ net.Addr, ctxErr error) {
host, port, err := splitHostPort(address)
if err != nil {
return nil, err
}
if deadline, ok := ctx.Deadline(); ok && !deadline.IsZero() {
c.SetDeadline(deadline)
defer c.SetDeadline(noDeadline)
}
if ctx != context.Background() {
errCh := make(chan error, 1)
done := make(chan struct{})
defer func() {
close(done)
if ctxErr == nil {
ctxErr = <-errCh
}
}()
go func() {
select {
case <-ctx.Done():
c.SetDeadline(aLongTimeAgo)
errCh <- ctx.Err()
case <-done:
errCh <- nil
}
}()
}
b := make([]byte, 0, 6+len(host)) // the size here is just an estimate
b = append(b, Version5)
if len(d.AuthMethods) == 0 || d.Authenticate == nil {
b = append(b, 1, byte(AuthMethodNotRequired))
} else {
ams := d.AuthMethods
if len(ams) > 255 {
return nil, errors.New("too many authentication methods")
}
b = append(b, byte(len(ams)))
for _, am := range ams {
b = append(b, byte(am))
}
}
if _, ctxErr = c.Write(b); ctxErr != nil {
return
}
if _, ctxErr = io.ReadFull(c, b[:2]); ctxErr != nil {
return
}
if b[0] != Version5 {
return nil, errors.New("unexpected protocol version " + strconv.Itoa(int(b[0])))
}
am := AuthMethod(b[1])
if am == AuthMethodNoAcceptableMethods {
return nil, errors.New("no acceptable authentication methods")
}
if d.Authenticate != nil {
if ctxErr = d.Authenticate(ctx, c, am); ctxErr != nil {
return
}
}
b = b[:0]
b = append(b, Version5, byte(d.cmd), 0)
if ip := net.ParseIP(host); ip != nil {
if ip4 := ip.To4(); ip4 != nil {
b = append(b, AddrTypeIPv4)
b = append(b, ip4...)
} else if ip6 := ip.To16(); ip6 != nil {
b = append(b, AddrTypeIPv6)
b = append(b, ip6...)
} else {
return nil, errors.New("unknown address type")
}
} else {
if len(host) > 255 {
return nil, errors.New("FQDN too long")
}
b = append(b, AddrTypeFQDN)
b = append(b, byte(len(host)))
b = append(b, host...)
}
b = append(b, byte(port>>8), byte(port))
if _, ctxErr = c.Write(b); ctxErr != nil {
return
}
if _, ctxErr = io.ReadFull(c, b[:4]); ctxErr != nil {
return
}
if b[0] != Version5 {
return nil, errors.New("unexpected protocol version " + strconv.Itoa(int(b[0])))
}
if cmdErr := Reply(b[1]); cmdErr != StatusSucceeded {
return nil, errors.New("unknown error " + cmdErr.String())
}
if b[2] != 0 {
return nil, errors.New("non-zero reserved field")
}
l := 2
var a Addr
switch b[3] {
case AddrTypeIPv4:
l += net.IPv4len
a.IP = make(net.IP, net.IPv4len)
case AddrTypeIPv6:
l += net.IPv6len
a.IP = make(net.IP, net.IPv6len)
case AddrTypeFQDN:
if _, err := io.ReadFull(c, b[:1]); err != nil {
return nil, err
}
l += int(b[0])
default:
return nil, errors.New("unknown address type " + strconv.Itoa(int(b[3])))
}
if cap(b) < l {
b = make([]byte, l)
} else {
b = b[:l]
}
if _, ctxErr = io.ReadFull(c, b); ctxErr != nil {
return
}
if a.IP != nil {
copy(a.IP, b)
} else {
a.Name = string(b[:len(b)-2])
}
a.Port = int(b[len(b)-2])<<8 | int(b[len(b)-1])
return &a, nil
}
func splitHostPort(address string) (string, int, error) {
host, port, err := net.SplitHostPort(address)
if err != nil {
return "", 0, err
}
portnum, err := strconv.Atoi(port)
if err != nil {
return "", 0, err
}
if 1 > portnum || portnum > 0xffff {
return "", 0, errors.New("port number out of range " + port)
}
return host, portnum, nil
}

317
vendor/golang.org/x/net/internal/socks/socks.go generated vendored Normal file
View File

@ -0,0 +1,317 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package socks provides a SOCKS version 5 client implementation.
//
// SOCKS protocol version 5 is defined in RFC 1928.
// Username/Password authentication for SOCKS version 5 is defined in
// RFC 1929.
package socks
import (
"context"
"errors"
"io"
"net"
"strconv"
)
// A Command represents a SOCKS command.
type Command int
func (cmd Command) String() string {
switch cmd {
case CmdConnect:
return "socks connect"
case cmdBind:
return "socks bind"
default:
return "socks " + strconv.Itoa(int(cmd))
}
}
// An AuthMethod represents a SOCKS authentication method.
type AuthMethod int
// A Reply represents a SOCKS command reply code.
type Reply int
func (code Reply) String() string {
switch code {
case StatusSucceeded:
return "succeeded"
case 0x01:
return "general SOCKS server failure"
case 0x02:
return "connection not allowed by ruleset"
case 0x03:
return "network unreachable"
case 0x04:
return "host unreachable"
case 0x05:
return "connection refused"
case 0x06:
return "TTL expired"
case 0x07:
return "command not supported"
case 0x08:
return "address type not supported"
default:
return "unknown code: " + strconv.Itoa(int(code))
}
}
// Wire protocol constants.
const (
Version5 = 0x05
AddrTypeIPv4 = 0x01
AddrTypeFQDN = 0x03
AddrTypeIPv6 = 0x04
CmdConnect Command = 0x01 // establishes an active-open forward proxy connection
cmdBind Command = 0x02 // establishes a passive-open forward proxy connection
AuthMethodNotRequired AuthMethod = 0x00 // no authentication required
AuthMethodUsernamePassword AuthMethod = 0x02 // use username/password
AuthMethodNoAcceptableMethods AuthMethod = 0xff // no acceptable authentication methods
StatusSucceeded Reply = 0x00
)
// An Addr represents a SOCKS-specific address.
// Either Name or IP is used exclusively.
type Addr struct {
Name string // fully-qualified domain name
IP net.IP
Port int
}
func (a *Addr) Network() string { return "socks" }
func (a *Addr) String() string {
if a == nil {
return "<nil>"
}
port := strconv.Itoa(a.Port)
if a.IP == nil {
return net.JoinHostPort(a.Name, port)
}
return net.JoinHostPort(a.IP.String(), port)
}
// A Conn represents a forward proxy connection.
type Conn struct {
net.Conn
boundAddr net.Addr
}
// BoundAddr returns the address assigned by the proxy server for
// connecting to the command target address from the proxy server.
func (c *Conn) BoundAddr() net.Addr {
if c == nil {
return nil
}
return c.boundAddr
}
// A Dialer holds SOCKS-specific options.
type Dialer struct {
cmd Command // either CmdConnect or cmdBind
proxyNetwork string // network between a proxy server and a client
proxyAddress string // proxy server address
// ProxyDial specifies the optional dial function for
// establishing the transport connection.
ProxyDial func(context.Context, string, string) (net.Conn, error)
// AuthMethods specifies the list of request authentication
// methods.
// If empty, SOCKS client requests only AuthMethodNotRequired.
AuthMethods []AuthMethod
// Authenticate specifies the optional authentication
// function. It must be non-nil when AuthMethods is not empty.
// It must return an error when the authentication is failed.
Authenticate func(context.Context, io.ReadWriter, AuthMethod) error
}
// DialContext connects to the provided address on the provided
// network.
//
// The returned error value may be a net.OpError. When the Op field of
// net.OpError contains "socks", the Source field contains a proxy
// server address and the Addr field contains a command target
// address.
//
// See func Dial of the net package of standard library for a
// description of the network and address parameters.
func (d *Dialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
if err := d.validateTarget(network, address); err != nil {
proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
}
if ctx == nil {
proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New("nil context")}
}
var err error
var c net.Conn
if d.ProxyDial != nil {
c, err = d.ProxyDial(ctx, d.proxyNetwork, d.proxyAddress)
} else {
var dd net.Dialer
c, err = dd.DialContext(ctx, d.proxyNetwork, d.proxyAddress)
}
if err != nil {
proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
}
a, err := d.connect(ctx, c, address)
if err != nil {
c.Close()
proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
}
return &Conn{Conn: c, boundAddr: a}, nil
}
// DialWithConn initiates a connection from SOCKS server to the target
// network and address using the connection c that is already
// connected to the SOCKS server.
//
// It returns the connection's local address assigned by the SOCKS
// server.
func (d *Dialer) DialWithConn(ctx context.Context, c net.Conn, network, address string) (net.Addr, error) {
if err := d.validateTarget(network, address); err != nil {
proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
}
if ctx == nil {
proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New("nil context")}
}
a, err := d.connect(ctx, c, address)
if err != nil {
proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
}
return a, nil
}
// Dial connects to the provided address on the provided network.
//
// Unlike DialContext, it returns a raw transport connection instead
// of a forward proxy connection.
//
// Deprecated: Use DialContext or DialWithConn instead.
func (d *Dialer) Dial(network, address string) (net.Conn, error) {
if err := d.validateTarget(network, address); err != nil {
proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
}
var err error
var c net.Conn
if d.ProxyDial != nil {
c, err = d.ProxyDial(context.Background(), d.proxyNetwork, d.proxyAddress)
} else {
c, err = net.Dial(d.proxyNetwork, d.proxyAddress)
}
if err != nil {
proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
}
if _, err := d.DialWithConn(context.Background(), c, network, address); err != nil {
c.Close()
return nil, err
}
return c, nil
}
func (d *Dialer) validateTarget(network, address string) error {
switch network {
case "tcp", "tcp6", "tcp4":
default:
return errors.New("network not implemented")
}
switch d.cmd {
case CmdConnect, cmdBind:
default:
return errors.New("command not implemented")
}
return nil
}
func (d *Dialer) pathAddrs(address string) (proxy, dst net.Addr, err error) {
for i, s := range []string{d.proxyAddress, address} {
host, port, err := splitHostPort(s)
if err != nil {
return nil, nil, err
}
a := &Addr{Port: port}
a.IP = net.ParseIP(host)
if a.IP == nil {
a.Name = host
}
if i == 0 {
proxy = a
} else {
dst = a
}
}
return
}
// NewDialer returns a new Dialer that dials through the provided
// proxy server's network and address.
func NewDialer(network, address string) *Dialer {
return &Dialer{proxyNetwork: network, proxyAddress: address, cmd: CmdConnect}
}
const (
authUsernamePasswordVersion = 0x01
authStatusSucceeded = 0x00
)
// UsernamePassword are the credentials for the username/password
// authentication method.
type UsernamePassword struct {
Username string
Password string
}
// Authenticate authenticates a pair of username and password with the
// proxy server.
func (up *UsernamePassword) Authenticate(ctx context.Context, rw io.ReadWriter, auth AuthMethod) error {
switch auth {
case AuthMethodNotRequired:
return nil
case AuthMethodUsernamePassword:
if len(up.Username) == 0 || len(up.Username) > 255 || len(up.Password) == 0 || len(up.Password) > 255 {
return errors.New("invalid username/password")
}
b := []byte{authUsernamePasswordVersion}
b = append(b, byte(len(up.Username)))
b = append(b, up.Username...)
b = append(b, byte(len(up.Password)))
b = append(b, up.Password...)
// TODO(mikio): handle IO deadlines and cancelation if
// necessary
if _, err := rw.Write(b); err != nil {
return err
}
if _, err := io.ReadFull(rw, b[:2]); err != nil {
return err
}
if b[0] != authUsernamePasswordVersion {
return errors.New("invalid username/password version")
}
if b[1] != authStatusSucceeded {
return errors.New("username/password authentication failed")
}
return nil
}
return errors.New("unsupported authentication method " + strconv.Itoa(int(auth)))
}

54
vendor/golang.org/x/net/proxy/dial.go generated vendored Normal file
View File

@ -0,0 +1,54 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package proxy
import (
"context"
"net"
)
// A ContextDialer dials using a context.
type ContextDialer interface {
DialContext(ctx context.Context, network, address string) (net.Conn, error)
}
// Dial works like DialContext on net.Dialer but using a dialer returned by FromEnvironment.
//
// The passed ctx is only used for returning the Conn, not the lifetime of the Conn.
//
// Custom dialers (registered via RegisterDialerType) that do not implement ContextDialer
// can leak a goroutine for as long as it takes the underlying Dialer implementation to timeout.
//
// A Conn returned from a successful Dial after the context has been cancelled will be immediately closed.
func Dial(ctx context.Context, network, address string) (net.Conn, error) {
d := FromEnvironment()
if xd, ok := d.(ContextDialer); ok {
return xd.DialContext(ctx, network, address)
}
return dialContext(ctx, d, network, address)
}
// WARNING: this can leak a goroutine for as long as the underlying Dialer implementation takes to timeout
// A Conn returned from a successful Dial after the context has been cancelled will be immediately closed.
func dialContext(ctx context.Context, d Dialer, network, address string) (net.Conn, error) {
var (
conn net.Conn
done = make(chan struct{}, 1)
err error
)
go func() {
conn, err = d.Dial(network, address)
close(done)
if conn != nil && ctx.Err() != nil {
conn.Close()
}
}()
select {
case <-ctx.Done():
err = ctx.Err()
case <-done:
}
return conn, err
}

31
vendor/golang.org/x/net/proxy/direct.go generated vendored Normal file
View File

@ -0,0 +1,31 @@
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package proxy
import (
"context"
"net"
)
type direct struct{}
// Direct implements Dialer by making network connections directly using net.Dial or net.DialContext.
var Direct = direct{}
var (
_ Dialer = Direct
_ ContextDialer = Direct
)
// Dial directly invokes net.Dial with the supplied parameters.
func (direct) Dial(network, addr string) (net.Conn, error) {
return net.Dial(network, addr)
}
// DialContext instantiates a net.Dialer and invokes its DialContext receiver with the supplied parameters.
func (direct) DialContext(ctx context.Context, network, addr string) (net.Conn, error) {
var d net.Dialer
return d.DialContext(ctx, network, addr)
}

155
vendor/golang.org/x/net/proxy/per_host.go generated vendored Normal file
View File

@ -0,0 +1,155 @@
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package proxy
import (
"context"
"net"
"strings"
)
// A PerHost directs connections to a default Dialer unless the host name
// requested matches one of a number of exceptions.
type PerHost struct {
def, bypass Dialer
bypassNetworks []*net.IPNet
bypassIPs []net.IP
bypassZones []string
bypassHosts []string
}
// NewPerHost returns a PerHost Dialer that directs connections to either
// defaultDialer or bypass, depending on whether the connection matches one of
// the configured rules.
func NewPerHost(defaultDialer, bypass Dialer) *PerHost {
return &PerHost{
def: defaultDialer,
bypass: bypass,
}
}
// Dial connects to the address addr on the given network through either
// defaultDialer or bypass.
func (p *PerHost) Dial(network, addr string) (c net.Conn, err error) {
host, _, err := net.SplitHostPort(addr)
if err != nil {
return nil, err
}
return p.dialerForRequest(host).Dial(network, addr)
}
// DialContext connects to the address addr on the given network through either
// defaultDialer or bypass.
func (p *PerHost) DialContext(ctx context.Context, network, addr string) (c net.Conn, err error) {
host, _, err := net.SplitHostPort(addr)
if err != nil {
return nil, err
}
d := p.dialerForRequest(host)
if x, ok := d.(ContextDialer); ok {
return x.DialContext(ctx, network, addr)
}
return dialContext(ctx, d, network, addr)
}
func (p *PerHost) dialerForRequest(host string) Dialer {
if ip := net.ParseIP(host); ip != nil {
for _, net := range p.bypassNetworks {
if net.Contains(ip) {
return p.bypass
}
}
for _, bypassIP := range p.bypassIPs {
if bypassIP.Equal(ip) {
return p.bypass
}
}
return p.def
}
for _, zone := range p.bypassZones {
if strings.HasSuffix(host, zone) {
return p.bypass
}
if host == zone[1:] {
// For a zone ".example.com", we match "example.com"
// too.
return p.bypass
}
}
for _, bypassHost := range p.bypassHosts {
if bypassHost == host {
return p.bypass
}
}
return p.def
}
// AddFromString parses a string that contains comma-separated values
// specifying hosts that should use the bypass proxy. Each value is either an
// IP address, a CIDR range, a zone (*.example.com) or a host name
// (localhost). A best effort is made to parse the string and errors are
// ignored.
func (p *PerHost) AddFromString(s string) {
hosts := strings.Split(s, ",")
for _, host := range hosts {
host = strings.TrimSpace(host)
if len(host) == 0 {
continue
}
if strings.Contains(host, "/") {
// We assume that it's a CIDR address like 127.0.0.0/8
if _, net, err := net.ParseCIDR(host); err == nil {
p.AddNetwork(net)
}
continue
}
if ip := net.ParseIP(host); ip != nil {
p.AddIP(ip)
continue
}
if strings.HasPrefix(host, "*.") {
p.AddZone(host[1:])
continue
}
p.AddHost(host)
}
}
// AddIP specifies an IP address that will use the bypass proxy. Note that
// this will only take effect if a literal IP address is dialed. A connection
// to a named host will never match an IP.
func (p *PerHost) AddIP(ip net.IP) {
p.bypassIPs = append(p.bypassIPs, ip)
}
// AddNetwork specifies an IP range that will use the bypass proxy. Note that
// this will only take effect if a literal IP address is dialed. A connection
// to a named host will never match.
func (p *PerHost) AddNetwork(net *net.IPNet) {
p.bypassNetworks = append(p.bypassNetworks, net)
}
// AddZone specifies a DNS suffix that will use the bypass proxy. A zone of
// "example.com" matches "example.com" and all of its subdomains.
func (p *PerHost) AddZone(zone string) {
if strings.HasSuffix(zone, ".") {
zone = zone[:len(zone)-1]
}
if !strings.HasPrefix(zone, ".") {
zone = "." + zone
}
p.bypassZones = append(p.bypassZones, zone)
}
// AddHost specifies a host name that will use the bypass proxy.
func (p *PerHost) AddHost(host string) {
if strings.HasSuffix(host, ".") {
host = host[:len(host)-1]
}
p.bypassHosts = append(p.bypassHosts, host)
}

149
vendor/golang.org/x/net/proxy/proxy.go generated vendored Normal file
View File

@ -0,0 +1,149 @@
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package proxy provides support for a variety of protocols to proxy network
// data.
package proxy // import "golang.org/x/net/proxy"
import (
"errors"
"net"
"net/url"
"os"
"sync"
)
// A Dialer is a means to establish a connection.
// Custom dialers should also implement ContextDialer.
type Dialer interface {
// Dial connects to the given address via the proxy.
Dial(network, addr string) (c net.Conn, err error)
}
// Auth contains authentication parameters that specific Dialers may require.
type Auth struct {
User, Password string
}
// FromEnvironment returns the dialer specified by the proxy-related
// variables in the environment and makes underlying connections
// directly.
func FromEnvironment() Dialer {
return FromEnvironmentUsing(Direct)
}
// FromEnvironmentUsing returns the dialer specify by the proxy-related
// variables in the environment and makes underlying connections
// using the provided forwarding Dialer (for instance, a *net.Dialer
// with desired configuration).
func FromEnvironmentUsing(forward Dialer) Dialer {
allProxy := allProxyEnv.Get()
if len(allProxy) == 0 {
return forward
}
proxyURL, err := url.Parse(allProxy)
if err != nil {
return forward
}
proxy, err := FromURL(proxyURL, forward)
if err != nil {
return forward
}
noProxy := noProxyEnv.Get()
if len(noProxy) == 0 {
return proxy
}
perHost := NewPerHost(proxy, forward)
perHost.AddFromString(noProxy)
return perHost
}
// proxySchemes is a map from URL schemes to a function that creates a Dialer
// from a URL with such a scheme.
var proxySchemes map[string]func(*url.URL, Dialer) (Dialer, error)
// RegisterDialerType takes a URL scheme and a function to generate Dialers from
// a URL with that scheme and a forwarding Dialer. Registered schemes are used
// by FromURL.
func RegisterDialerType(scheme string, f func(*url.URL, Dialer) (Dialer, error)) {
if proxySchemes == nil {
proxySchemes = make(map[string]func(*url.URL, Dialer) (Dialer, error))
}
proxySchemes[scheme] = f
}
// FromURL returns a Dialer given a URL specification and an underlying
// Dialer for it to make network requests.
func FromURL(u *url.URL, forward Dialer) (Dialer, error) {
var auth *Auth
if u.User != nil {
auth = new(Auth)
auth.User = u.User.Username()
if p, ok := u.User.Password(); ok {
auth.Password = p
}
}
switch u.Scheme {
case "socks5", "socks5h":
addr := u.Hostname()
port := u.Port()
if port == "" {
port = "1080"
}
return SOCKS5("tcp", net.JoinHostPort(addr, port), auth, forward)
}
// If the scheme doesn't match any of the built-in schemes, see if it
// was registered by another package.
if proxySchemes != nil {
if f, ok := proxySchemes[u.Scheme]; ok {
return f(u, forward)
}
}
return nil, errors.New("proxy: unknown scheme: " + u.Scheme)
}
var (
allProxyEnv = &envOnce{
names: []string{"ALL_PROXY", "all_proxy"},
}
noProxyEnv = &envOnce{
names: []string{"NO_PROXY", "no_proxy"},
}
)
// envOnce looks up an environment variable (optionally by multiple
// names) once. It mitigates expensive lookups on some platforms
// (e.g. Windows).
// (Borrowed from net/http/transport.go)
type envOnce struct {
names []string
once sync.Once
val string
}
func (e *envOnce) Get() string {
e.once.Do(e.init)
return e.val
}
func (e *envOnce) init() {
for _, n := range e.names {
e.val = os.Getenv(n)
if e.val != "" {
return
}
}
}
// reset is used by tests
func (e *envOnce) reset() {
e.once = sync.Once{}
e.val = ""
}

42
vendor/golang.org/x/net/proxy/socks5.go generated vendored Normal file
View File

@ -0,0 +1,42 @@
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package proxy
import (
"context"
"net"
"golang.org/x/net/internal/socks"
)
// SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given
// address with an optional username and password.
// See RFC 1928 and RFC 1929.
func SOCKS5(network, address string, auth *Auth, forward Dialer) (Dialer, error) {
d := socks.NewDialer(network, address)
if forward != nil {
if f, ok := forward.(ContextDialer); ok {
d.ProxyDial = func(ctx context.Context, network string, address string) (net.Conn, error) {
return f.DialContext(ctx, network, address)
}
} else {
d.ProxyDial = func(ctx context.Context, network string, address string) (net.Conn, error) {
return dialContext(ctx, forward, network, address)
}
}
}
if auth != nil {
up := socks.UsernamePassword{
Username: auth.User,
Password: auth.Password,
}
d.AuthMethods = []socks.AuthMethod{
socks.AuthMethodNotRequired,
socks.AuthMethodUsernamePassword,
}
d.Authenticate = up.Authenticate
}
return d, nil
}

6
vendor/gopkg.in/irc.v3/.gitignore generated vendored Normal file
View File

@ -0,0 +1,6 @@
*.cover
*.test
*.out
# As this is a library, we ignore go.sum
go.sum

3
vendor/gopkg.in/irc.v3/.gitmodules generated vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "testcases"]
path = testcases
url = https://github.com/go-irc/irc-parser-tests/

15
vendor/gopkg.in/irc.v3/.golangci.yml generated vendored Normal file
View File

@ -0,0 +1,15 @@
linters:
enable-all: true
disable:
- gochecknoglobals
- gomnd
# TODO: re-enable these
- errcheck
- funlen
# TODO: maybe re-enable these
- godox
- wsl
linters-settings:
govet:
check-shadowing: true

18
vendor/gopkg.in/irc.v3/LICENSE generated vendored Normal file
View File

@ -0,0 +1,18 @@
Copyright 2016 Kaleb Elwert
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

108
vendor/gopkg.in/irc.v3/README.md generated vendored Normal file
View File

@ -0,0 +1,108 @@
# go-irc
[![GoDoc](https://img.shields.io/badge/doc-GoDoc-blue.svg)](https://godoc.org/github.com/go-irc/irc)
[![Build Status](https://img.shields.io/github/workflow/status/go-irc/irc/CI.svg)](https://github.com/go-irc/irc/actions)
[![Coverage Status](https://img.shields.io/coveralls/go-irc/irc.svg)](https://coveralls.io/github/go-irc/irc?branch=master)
This package was originally created to only handle message parsing,
but has since been expanded to include a small abstraction around a
connection and a simple client.
This library is not designed to hide any of the IRC elements from
you. If you just want to build a simple chat bot and don't want to
deal with IRC in particular, there are a number of other libraries
which provide a more full featured client if that's what you're
looking for.
This library is meant to stay as simple as possible so it can be a
building block for other packages.
This library aims for API compatibility whenever possible. New
functions and other additions will most likely not result in a major
version increase unless they break the API. This library aims to
follow the semver recommendations mentioned on gopkg.in.
Due to complications in how to support x/net/context vs the built-in context
package, only go 1.7+ is officially supported.
## Import Paths
All development happens on the `master` branch and when features are
considered stable enough, a new release will be tagged.
* `gopkg.in/irc.v3` should be used to develop against the commits
tagged as stable
* In previous versions, `github.com/go-irc/irc` used to be able to be
used to develop against the master branch but module support in go
seems to have broken this.
## Development
In order to run the tests, make sure all submodules are up to date. If you are
just using this library, these are not needed.
## Example
```go
package main
import (
"log"
"net"
"gopkg.in/irc.v3"
)
func main() {
conn, err := net.Dial("tcp", "chat.freenode.net:6667")
if err != nil {
log.Fatalln(err)
}
config := irc.ClientConfig{
Nick: "i_have_a_nick",
Pass: "password",
User: "username",
Name: "Full Name",
Handler: irc.HandlerFunc(func(c *irc.Client, m *irc.Message) {
if m.Command == "001" {
// 001 is a welcome event, so we join channels there
c.Write("JOIN #bot-test-chan")
} else if m.Command == "PRIVMSG" && c.FromChannel(m) {
// Create a handler on all messages.
c.WriteMessage(&irc.Message{
Command: "PRIVMSG",
Params: []string{
m.Params[0],
m.Trailing(),
},
})
}
}),
}
// Create the client
client := irc.NewClient(conn, config)
err = client.Run()
if err != nil {
log.Fatalln(err)
}
}
```
## Major Version Changes
### v1
Initial release
### v2
- CTCP messages will no longer be rewritten. The decision was made that this
library should pass through all messages without mangling them.
- Remove Message.FromChannel as this is not always accurate, while
Client.FromChannel should always be accurate.
### v3
- Import path changed back to `gopkg.in/irc.v3` without the version suffix.

338
vendor/gopkg.in/irc.v3/client.go generated vendored Normal file
View File

@ -0,0 +1,338 @@
package irc
import (
"context"
"errors"
"fmt"
"io"
"sync"
"time"
)
// ClientConfig is a structure used to configure a Client.
type ClientConfig struct {
// General connection information.
Nick string
Pass string
User string
Name string
// Connection settings
PingFrequency time.Duration
PingTimeout time.Duration
// SendLimit is how frequent messages can be sent. If this is zero,
// there will be no limit.
SendLimit time.Duration
// SendBurst is the number of messages which can be sent in a burst.
SendBurst int
// Handler is used for message dispatching.
Handler Handler
}
type cap struct {
// Requested means that this cap was requested by the user
Requested bool
// Required will be true if this cap is non-optional
Required bool
// Enabled means that this cap was accepted by the server
Enabled bool
// Available means that the server supports this cap
Available bool
}
// Client is a wrapper around Conn which is designed to make common operations
// much simpler.
type Client struct {
*Conn
rwc io.ReadWriteCloser
config ClientConfig
// Internal state
currentNick string
limiter chan struct{}
incomingPongChan chan string
errChan chan error
caps map[string]cap
remainingCapResponses int
connected bool
}
// NewClient creates a client given an io stream and a client config.
func NewClient(rwc io.ReadWriteCloser, config ClientConfig) *Client {
c := &Client{
Conn: NewConn(rwc),
rwc: rwc,
config: config,
errChan: make(chan error, 1),
caps: make(map[string]cap),
}
// Replace the writer writeCallback with one of our own
c.Conn.Writer.writeCallback = c.writeCallback
return c
}
func (c *Client) writeCallback(w *Writer, line string) error {
if c.limiter != nil {
<-c.limiter
}
_, err := w.writer.Write([]byte(line + "\r\n"))
if err != nil {
c.sendError(err)
}
return err
}
// maybeStartLimiter will start a ticker which will limit how quickly messages
// can be written to the connection if the SendLimit is set in the config.
func (c *Client) maybeStartLimiter(wg *sync.WaitGroup, exiting chan struct{}) {
if c.config.SendLimit == 0 {
return
}
wg.Add(1)
// If SendBurst is 0, this will be unbuffered, so keep that in mind.
c.limiter = make(chan struct{}, c.config.SendBurst)
limitTick := time.NewTicker(c.config.SendLimit)
go func() {
defer wg.Done()
var done bool
for !done {
select {
case <-limitTick.C:
select {
case c.limiter <- struct{}{}:
default:
}
case <-exiting:
done = true
}
}
limitTick.Stop()
close(c.limiter)
c.limiter = nil
}()
}
// maybeStartPingLoop will start a goroutine to send out PING messages at the
// PingFrequency in the config if the frequency is not 0.
func (c *Client) maybeStartPingLoop(wg *sync.WaitGroup, exiting chan struct{}) {
if c.config.PingFrequency <= 0 {
return
}
wg.Add(1)
c.incomingPongChan = make(chan string, 5)
go func() {
defer wg.Done()
pingHandlers := make(map[string]chan struct{})
ticker := time.NewTicker(c.config.PingFrequency)
defer ticker.Stop()
for {
select {
case <-ticker.C:
// Each time we get a tick, we send off a ping and start a
// goroutine to handle the pong.
timestamp := time.Now().Unix()
pongChan := make(chan struct{}, 1)
pingHandlers[fmt.Sprintf("%d", timestamp)] = pongChan
wg.Add(1)
go c.handlePing(timestamp, pongChan, wg, exiting)
case data := <-c.incomingPongChan:
// Make sure the pong gets routed to the correct
// goroutine.
c := pingHandlers[data]
delete(pingHandlers, data)
if c != nil {
c <- struct{}{}
}
case <-exiting:
return
}
}
}()
}
func (c *Client) handlePing(timestamp int64, pongChan chan struct{}, wg *sync.WaitGroup, exiting chan struct{}) {
defer wg.Done()
c.Writef("PING :%d", timestamp)
timer := time.NewTimer(c.config.PingTimeout)
defer timer.Stop()
select {
case <-timer.C:
c.sendError(errors.New("ping timeout"))
case <-pongChan:
return
case <-exiting:
return
}
}
// maybeStartCapHandshake will run a CAP LS and all the relevant CAP REQ
// commands if there are any CAPs requested.
func (c *Client) maybeStartCapHandshake() {
if len(c.caps) == 0 {
return
}
c.Write("CAP LS")
c.remainingCapResponses = 1 // We count the CAP LS response as a normal response
for key, cap := range c.caps {
if cap.Requested {
c.Writef("CAP REQ :%s", key)
c.remainingCapResponses++
}
}
}
// CapRequest allows you to request IRCv3 capabilities from the server during
// the handshake. The behavior is undefined if this is called before the
// handshake completes so it is recommended that this be called before Run. If
// the CAP is marked as required, the client will exit if that CAP could not be
// negotiated during the handshake.
func (c *Client) CapRequest(capName string, required bool) {
cap := c.caps[capName]
cap.Requested = true
cap.Required = cap.Required || required
c.caps[capName] = cap
}
// CapEnabled allows you to check if a CAP is enabled for this connection. Note
// that it will not be populated until after the CAP handshake is done, so it is
// recommended to wait to check this until after a message like 001.
func (c *Client) CapEnabled(capName string) bool {
return c.caps[capName].Enabled
}
// CapAvailable allows you to check if a CAP is available on this server. Note
// that it will not be populated until after the CAP handshake is done, so it is
// recommended to wait to check this until after a message like 001.
func (c *Client) CapAvailable(capName string) bool {
return c.caps[capName].Available
}
func (c *Client) sendError(err error) {
select {
case c.errChan <- err:
default:
}
}
func (c *Client) startReadLoop(wg *sync.WaitGroup, exiting chan struct{}) {
wg.Add(1)
go func() {
defer wg.Done()
for {
select {
case <-exiting:
return
default:
m, err := c.ReadMessage()
if err != nil {
c.sendError(err)
break
}
if f, ok := clientFilters[m.Command]; ok {
f(c, m)
}
if c.config.Handler != nil {
c.config.Handler.Handle(c, m)
}
}
}
}()
}
// Run starts the main loop for this IRC connection. Note that it may break in
// strange and unexpected ways if it is called again before the first connection
// exits.
func (c *Client) Run() error {
return c.RunContext(context.TODO())
}
// RunContext is the same as Run but a context.Context can be passed in for
// cancelation.
func (c *Client) RunContext(ctx context.Context) error {
// exiting is used by the main goroutine here to ensure any sub-goroutines
// get closed when exiting.
exiting := make(chan struct{})
var wg sync.WaitGroup
c.maybeStartLimiter(&wg, exiting)
c.maybeStartPingLoop(&wg, exiting)
c.currentNick = c.config.Nick
if c.config.Pass != "" {
c.Writef("PASS :%s", c.config.Pass)
}
c.maybeStartCapHandshake()
// This feels wrong because it results in CAP LS, CAP REQ, NICK, USER, CAP
// END, but it works and lets us keep the code a bit simpler.
c.Writef("NICK :%s", c.config.Nick)
c.Writef("USER %s 0 * :%s", c.config.User, c.config.Name)
// Now that the handshake is pretty much done, we can start listening for
// messages.
c.startReadLoop(&wg, exiting)
// Wait for an error from any goroutine or for the context to time out, then
// signal we're exiting and wait for the goroutines to exit.
var err error
select {
case err = <-c.errChan:
case <-ctx.Done():
}
close(exiting)
c.rwc.Close()
wg.Wait()
return err
}
// CurrentNick returns what the nick of the client is known to be at this point
// in time.
func (c *Client) CurrentNick() string {
return c.currentNick
}
// FromChannel takes a Message representing a PRIVMSG and returns if that
// message came from a channel or directly from a user.
func (c *Client) FromChannel(m *Message) bool {
if len(m.Params) < 1 {
return false
}
// The first param is the target, so if this doesn't match the current nick,
// the message came from a channel.
return m.Params[0] != c.currentNick
}

151
vendor/gopkg.in/irc.v3/client_handlers.go generated vendored Normal file
View File

@ -0,0 +1,151 @@
package irc
import (
"fmt"
"strings"
)
type clientFilter func(*Client, *Message)
// clientFilters are pre-processing which happens for certain message
// types. These were moved from below to keep the complexity of each
// component down.
var clientFilters = map[string]clientFilter{
"001": handle001,
"433": handle433,
"437": handle437,
"PING": handlePing,
"PONG": handlePong,
"NICK": handleNick,
"CAP": handleCap,
}
// From rfc2812 section 5.1 (Command responses)
//
// 001 RPL_WELCOME
// "Welcome to the Internet Relay Network
// <nick>!<user>@<host>"
func handle001(c *Client, m *Message) {
c.currentNick = m.Params[0]
c.connected = true
}
// From rfc2812 section 5.2 (Error Replies)
//
// 433 ERR_NICKNAMEINUSE
// "<nick> :Nickname is already in use"
//
// - Returned when a NICK message is processed that results
// in an attempt to change to a currently existing
// nickname.
func handle433(c *Client, m *Message) {
// We only want to try and handle nick collisions during the initial
// handshake.
if c.connected {
return
}
c.currentNick += "_"
c.Writef("NICK :%s", c.currentNick)
}
// From rfc2812 section 5.2 (Error Replies)
//
// 437 ERR_UNAVAILRESOURCE
// "<nick/channel> :Nick/channel is temporarily unavailable"
//
// - Returned by a server to a user trying to join a channel
// currently blocked by the channel delay mechanism.
//
// - Returned by a server to a user trying to change nickname
// when the desired nickname is blocked by the nick delay
// mechanism.
func handle437(c *Client, m *Message) {
// We only want to try and handle nick collisions during the initial
// handshake.
if c.connected {
return
}
c.currentNick += "_"
c.Writef("NICK :%s", c.currentNick)
}
func handlePing(c *Client, m *Message) {
reply := m.Copy()
reply.Command = "PONG"
c.WriteMessage(reply)
}
func handlePong(c *Client, m *Message) {
if c.incomingPongChan != nil {
select {
case c.incomingPongChan <- m.Trailing():
default:
// Note that this return isn't really needed, but it helps some code
// coverage tools actually see this line.
return
}
}
}
func handleNick(c *Client, m *Message) {
if m.Prefix.Name == c.currentNick && len(m.Params) > 0 {
c.currentNick = m.Params[0]
}
}
var capFilters = map[string]clientFilter{
"LS": handleCapLs,
"ACK": handleCapAck,
"NAK": handleCapNak,
}
func handleCap(c *Client, m *Message) {
if c.remainingCapResponses <= 0 || len(m.Params) <= 2 {
return
}
if filter, ok := capFilters[m.Params[1]]; ok {
filter(c, m)
}
if c.remainingCapResponses <= 0 {
for key, cap := range c.caps {
if cap.Required && !cap.Enabled {
c.sendError(fmt.Errorf("CAP %s requested but not accepted", key))
return
}
}
c.Write("CAP END")
}
}
func handleCapLs(c *Client, m *Message) {
for _, key := range strings.Split(m.Trailing(), " ") {
cap := c.caps[key]
cap.Available = true
c.caps[key] = cap
}
c.remainingCapResponses--
}
func handleCapAck(c *Client, m *Message) {
for _, key := range strings.Split(m.Trailing(), " ") {
cap := c.caps[key]
cap.Enabled = true
c.caps[key] = cap
}
c.remainingCapResponses--
}
func handleCapNak(c *Client, m *Message) {
// If we got a NAK and this REQ was required, we need to bail
// with an error.
for _, key := range strings.Split(m.Trailing(), " ") {
if c.caps[key].Required {
c.sendError(fmt.Errorf("CAP %s requested but was rejected", key))
return
}
}
c.remainingCapResponses--
}

111
vendor/gopkg.in/irc.v3/conn.go generated vendored Normal file
View File

@ -0,0 +1,111 @@
package irc
import (
"bufio"
"fmt"
"io"
)
// Conn represents a simple IRC client. It embeds an irc.Reader and an
// irc.Writer.
type Conn struct {
*Reader
*Writer
}
// NewConn creates a new Conn
func NewConn(rw io.ReadWriter) *Conn {
return &Conn{
NewReader(rw),
NewWriter(rw),
}
}
// Writer is the outgoing side of a connection.
type Writer struct {
// DebugCallback is called for each outgoing message. The name of this may
// not be stable.
DebugCallback func(line string)
// Internal fields
writer io.Writer
writeCallback func(w *Writer, line string) error
}
func defaultWriteCallback(w *Writer, line string) error {
_, err := w.writer.Write([]byte(line + "\r\n"))
return err
}
// NewWriter creates an irc.Writer from an io.Writer.
func NewWriter(w io.Writer) *Writer {
return &Writer{nil, w, defaultWriteCallback}
}
// Write is a simple function which will write the given line to the
// underlying connection.
func (w *Writer) Write(line string) error {
if w.DebugCallback != nil {
w.DebugCallback(line)
}
return w.writeCallback(w, line)
}
// Writef is a wrapper around the connection's Write method and
// fmt.Sprintf. Simply use it to send a message as you would normally
// use fmt.Printf.
func (w *Writer) Writef(format string, args ...interface{}) error {
return w.Write(fmt.Sprintf(format, args...))
}
// WriteMessage writes the given message to the stream
func (w *Writer) WriteMessage(m *Message) error {
return w.Write(m.String())
}
// Reader is the incoming side of a connection. The data will be
// buffered, so do not re-use the io.Reader used to create the
// irc.Reader.
type Reader struct {
// DebugCallback is called for each incoming message. The name of this may
// not be stable.
DebugCallback func(string)
// Internal fields
reader *bufio.Reader
}
// NewReader creates an irc.Reader from an io.Reader. Note that once a reader is
// passed into this function, you should no longer use it as it is being used
// inside a bufio.Reader so you cannot rely on only the amount of data for a
// Message being read when you call ReadMessage.
func NewReader(r io.Reader) *Reader {
return &Reader{
nil,
bufio.NewReader(r),
}
}
// ReadMessage returns the next message from the stream or an error.
// It ignores empty messages.
func (r *Reader) ReadMessage() (msg *Message, err error) {
// It's valid for a message to be empty. Clients should ignore these,
// so we do to be good citizens.
err = ErrZeroLengthMessage
for err == ErrZeroLengthMessage {
var line string
line, err = r.reader.ReadString('\n')
if err != nil {
return nil, err
}
if r.DebugCallback != nil {
r.DebugCallback(line)
}
// Parse the message from our line
msg, err = ParseMessage(line)
}
return msg, err
}

8
vendor/gopkg.in/irc.v3/go.mod generated vendored Normal file
View File

@ -0,0 +1,8 @@
module gopkg.in/irc.v3
go 1.13
require (
github.com/stretchr/testify v1.4.0
gopkg.in/yaml.v2 v2.2.8
)

16
vendor/gopkg.in/irc.v3/handler.go generated vendored Normal file
View File

@ -0,0 +1,16 @@
package irc
// Handler is a simple interface meant for dispatching a message from
// a Client connection.
type Handler interface {
Handle(*Client, *Message)
}
// HandlerFunc is a simple wrapper around a function which allows it
// to be used as a Handler.
type HandlerFunc func(*Client, *Message)
// Handle calls f(c, m)
func (f HandlerFunc) Handle(c *Client, m *Message) {
f(c, m)
}

688
vendor/gopkg.in/irc.v3/numerics.go generated vendored Normal file
View File

@ -0,0 +1,688 @@
//nolint
package irc
const (
// RFC1459
RPL_TRACELINK = "200"
RPL_TRACECONNECTING = "201"
RPL_TRACEHANDSHAKE = "202"
RPL_TRACEUNKNOWN = "203"
RPL_TRACEOPERATOR = "204"
RPL_TRACEUSER = "205"
RPL_TRACESERVER = "206"
RPL_TRACENEWTYPE = "208"
RPL_STATSLINKINFO = "211"
RPL_STATSCOMMANDS = "212"
RPL_STATSCLINE = "213"
RPL_STATSNLINE = "214"
RPL_STATSILINE = "215"
RPL_STATSKLINE = "216"
RPL_STATSQLINE = "217"
RPL_STATSYLINE = "218"
RPL_ENDOFSTATS = "219"
RPL_UMODEIS = "221"
RPL_STATSLLINE = "241"
RPL_STATSUPTIME = "242"
RPL_STATSOLINE = "243"
RPL_STATSHLINE = "244"
RPL_LUSERCLIENT = "251"
RPL_LUSEROP = "252"
RPL_LUSERUNKNOWN = "253"
RPL_LUSERCHANNELS = "254"
RPL_LUSERME = "255"
RPL_ADMINME = "256"
RPL_ADMINLOC1 = "257"
RPL_ADMINLOC2 = "258"
RPL_ADMINEMAIL = "259"
RPL_TRACELOG = "261"
RPL_NONE = "300"
RPL_AWAY = "301"
RPL_USERHOST = "302"
RPL_ISON = "303"
RPL_UNAWAY = "305"
RPL_NOWAWAY = "306"
RPL_WHOISUSER = "311"
RPL_WHOISSERVER = "312"
RPL_WHOISOPERATOR = "313"
RPL_WHOWASUSER = "314"
RPL_ENDOFWHO = "315"
RPL_WHOISIDLE = "317"
RPL_ENDOFWHOIS = "318"
RPL_WHOISCHANNELS = "319"
RPL_LIST = "322"
RPL_LISTEND = "323"
RPL_CHANNELMODEIS = "324"
RPL_NOTOPIC = "331"
RPL_TOPIC = "332"
RPL_INVITING = "341"
RPL_VERSION = "351"
RPL_WHOREPLY = "352"
RPL_NAMREPLY = "353"
RPL_LINKS = "364"
RPL_ENDOFLINKS = "365"
RPL_ENDOFNAMES = "366"
RPL_BANLIST = "367"
RPL_ENDOFBANLIST = "368"
RPL_ENDOFWHOWAS = "369"
RPL_INFO = "371"
RPL_MOTD = "372"
RPL_ENDOFINFO = "374"
RPL_MOTDSTART = "375"
RPL_ENDOFMOTD = "376"
RPL_YOUREOPER = "381"
RPL_REHASHING = "382"
RPL_TIME = "391"
RPL_USERSSTART = "392"
RPL_USERS = "393"
RPL_ENDOFUSERS = "394"
RPL_NOUSERS = "395"
ERR_NOSUCHNICK = "401"
ERR_NOSUCHSERVER = "402"
ERR_NOSUCHCHANNEL = "403"
ERR_CANNOTSENDTOCHAN = "404"
ERR_TOOMANYCHANNELS = "405"
ERR_WASNOSUCHNICK = "406"
ERR_TOOMANYTARGETS = "407"
ERR_NOORIGIN = "409"
ERR_NORECIPIENT = "411"
ERR_NOTEXTTOSEND = "412"
ERR_NOTOPLEVEL = "413"
ERR_WILDTOPLEVEL = "414"
ERR_UNKNOWNCOMMAND = "421"
ERR_NOMOTD = "422"
ERR_NOADMININFO = "423"
ERR_FILEERROR = "424"
ERR_NONICKNAMEGIVEN = "431"
ERR_ERRONEUSNICKNAME = "432"
ERR_NICKNAMEINUSE = "433"
ERR_NICKCOLLISION = "436"
ERR_USERNOTINCHANNEL = "441"
ERR_NOTONCHANNEL = "442"
ERR_USERONCHANNEL = "443"
ERR_NOLOGIN = "444"
ERR_SUMMONDISABLED = "445"
ERR_USERSDISABLED = "446"
ERR_NOTREGISTERED = "451"
ERR_NEEDMOREPARAMS = "461"
ERR_ALREADYREGISTERED = "462"
ERR_NOPERMFORHOST = "463"
ERR_PASSWDMISMATCH = "464"
ERR_YOUREBANNEDCREEP = "465"
ERR_KEYSET = "467"
ERR_CHANNELISFULL = "471"
ERR_UNKNOWNMODE = "472"
ERR_INVITEONLYCHAN = "473"
ERR_BANNEDFROMCHAN = "474"
ERR_BADCHANNELKEY = "475"
ERR_NOPRIVILEGES = "481"
ERR_CHANOPRIVSNEEDED = "482"
ERR_CANTKILLSERVER = "483"
ERR_NOOPERHOST = "491"
ERR_UMODEUNKNOWNFLAG = "501"
ERR_USERSDONTMATCH = "502"
// RFC1459 (Obsolete)
RPL_SERVICEINFO = "231"
RPL_ENDOFSERVICES = "232"
RPL_SERVICE = "233"
RPL_WHOISCHANOP = "316"
RPL_LISTSTART = "321"
RPL_SUMMONING = "342"
RPL_KILLDONE = "361"
RPL_CLOSING = "362"
RPL_CLOSEEND = "363"
RPL_INFOSTART = "373"
RPL_MYPORTIS = "384"
ERR_YOUWILLBEBANNED = "466"
ERR_NOSERVICEHOST = "492"
// RFC2812
RPL_WELCOME = "001"
RPL_YOURHOST = "002"
RPL_CREATED = "003"
RPL_MYINFO = "004"
RPL_TRACESERVICE = "207"
RPL_TRACECLASS = "209"
RPL_SERVLIST = "234"
RPL_SERVLISTEND = "235"
RPL_STATSVLINE = "240"
RPL_STATSBLINE = "247"
RPL_STATSDLINE = "250"
RPL_TRACEEND = "262"
RPL_TRYAGAIN = "263"
RPL_UNIQOPIS = "325"
RPL_INVITELIST = "346"
RPL_ENDOFINVITELIST = "347"
RPL_EXCEPTLIST = "348"
RPL_ENDOFEXCEPTLIST = "349"
RPL_YOURESERVICE = "383"
ERR_NOSUCHSERVICE = "408"
ERR_BADMASK = "415"
ERR_UNAVAILRESOURCE = "437"
ERR_BADCHANMASK = "476"
ERR_NOCHANMODES = "477"
ERR_BANLISTFULL = "478"
ERR_RESTRICTED = "484"
ERR_UNIQOPRIVSNEEDED = "485"
// RFC2812 (Obsolete)
RPL_BOUNCE = "005"
RPL_TRACERECONNECT = "210"
RPL_STATSPING = "246"
// IRCv3
ERR_INVALIDCAPCMD = "410" // Undernet?
RPL_STARTTLS = "670"
ERR_STARTTLS = "691"
RPL_MONONLINE = "730" // RatBox
RPL_MONOFFLINE = "731" // RatBox
RPL_MONLIST = "732" // RatBox
RPL_ENDOFMONLIST = "733" // RatBox
ERR_MONLISTFULL = "734" // RatBox
RPL_WHOISKEYVALUE = "760"
RPL_KEYVALUE = "761"
RPL_METADATAEND = "762"
ERR_METADATALIMIT = "764"
ERR_TARGETINVALID = "765"
ERR_NOMATCHINGKEY = "766"
ERR_KEYINVALID = "767"
ERR_KEYNOTSET = "768"
ERR_KEYNOPERMISSION = "769"
RPL_LOGGEDIN = "900" // Charybdis/Atheme, IRCv3
RPL_LOGGEDOUT = "901" // Charybdis/Atheme, IRCv3
ERR_NICKLOCKED = "902" // Charybdis/Atheme, IRCv3
RPL_SASLSUCCESS = "903" // Charybdis/Atheme, IRCv3
ERR_SASLFAIL = "904" // Charybdis/Atheme, IRCv3
ERR_SASLTOOLONG = "905" // Charybdis/Atheme, IRCv3
ERR_SASLABORTED = "906" // Charybdis/Atheme, IRCv3
ERR_SASLALREADY = "907" // Charybdis/Atheme, IRCv3
RPL_SASLMECHS = "908" // Charybdis/Atheme, IRCv3
// Other
RPL_ISUPPORT = "005"
// Ignored
//
// Anything not in an RFC has not been included because
// there are way too many conflicts to deal with.
/*
RPL_MAP = "006" // Unreal
RPL_MAPEND = "007" // Unreal
RPL_SNOMASK = "008" // ircu
RPL_STATMEMTOT = "009" // ircu
RPL_BOUNCE = "010"
RPL_YOURCOOKIE = "014" // Hybrid?
RPL_MAP = "015" // ircu
RPL_MAPMORE = "016" // ircu
RPL_MAPEND = "017" // ircu
RPL_MAPUSERS = "018" // InspIRCd
RPL_HELLO = "020" // rusnet-ircd
RPL_APASSWARN_SET = "030" // ircu
RPL_APASSWARN_SECRET = "031" // ircu
RPL_APASSWARN_CLEAR = "032" // ircu
RPL_YOURID = "042" // IRCnet
RPL_SAVENICK = "043" // IRCnet
RPL_ATTEMPTINGJUNC = "050" // aircd
RPL_ATTEMPTINGREROUTE = "051" // aircd
RPL_REMOTEISUPPORT = "105" // Unreal
RPL_STATS = "210" // aircd
RPL_STATSHELP = "210" // Unreal
RPL_STATSPLINE = "217" // ircu
RPL_STATSPLINE = "220" // Hybrid
RPL_STATSBLINE = "220" // Bahamut, Unreal
RPL_STATSWLINE = "220" // Nefarious
RPL_MODLIST = "222"
RPL_SQLINE_NICK = "222" // Unreal
RPL_STATSBLINE = "222" // Bahamut
RPL_STATSJLINE = "222" // ircu
RPL_CODEPAGE = "222" // rusnet-ircd
RPL_STATSELINE = "223" // Bahamut
RPL_STATSGLINE = "223" // Unreal
RPL_CHARSET = "223" // rusnet-ircd
RPL_STATSFLINE = "224" // Hybrid, Bahamut
RPL_STATSTLINE = "224" // Unreal
RPL_STATSDLINE = "225" // Hybrid
RPL_STATSCLONE = "225" // Bahamut
RPL_STATSELINE = "225" // Unreal
RPL_STATSCOUNT = "226" // Bahamut
RPL_STATSALINE = "226" // Hybrid
RPL_STATSNLINE = "226" // Unreal
RPL_STATSGLINE = "227" // Bahamut
RPL_STATSVLINE = "227" // Unreal
RPL_STATSBLINE = "227" // Rizon
RPL_STATSQLINE = "228" // ircu
RPL_STATSBANVER = "228" // Unreal
RPL_STATSSPAMF = "229" // Unreal
RPL_STATSEXCEPTTKL = "230" // Unreal
RPL_RULES = "232" // Unreal
RPL_STATSVERBOSE = "236" // ircu
RPL_STATSENGINE = "237" // ircu
RPL_STATSFLINE = "238" // ircu
RPL_STATSIAUTH = "239" // IRCnet
RPL_STATSXLINE = "240" // AustHex
RPL_STATSSLINE = "245" // Bahamut, IRCnet, Hybrid
RPL_STATSTLINE = "245" // Hybrid?
RPL_STATSSERVICE = "246" // Hybrid
RPL_STATSTLINE = "246" // ircu
RPL_STATSULINE = "246" // Hybrid
RPL_STATSXLINE = "247" // Hybrid, PTlink, Unreal
RPL_STATSGLINE = "247" // ircu
RPL_STATSULINE = "248" // ircu
RPL_STATSDEFINE = "248" // IRCnet
RPL_STATSULINE = "249"
RPL_STATSDEBUG = "249" // Hybrid
RPL_STATSCONN = "250" // ircu, Unreal
RPL_TRACEPING = "262"
RPL_USINGSSL = "264" // rusnet-ircd
RPL_LOCALUSERS = "265" // aircd, Hybrid, Bahamut
RPL_GLOBALUSERS = "266" // aircd, Hybrid, Bahamut
RPL_START_NETSTAT = "267" // aircd
RPL_NETSTAT = "268" // aircd
RPL_END_NETSTAT = "269" // aircd
RPL_PRIVS = "270" // ircu
RPL_SILELIST = "271" // ircu
RPL_ENDOFSILELIST = "272" // ircu
RPL_NOTIFY = "273" // aircd
RPL_ENDNOTIFY = "274" // aircd
RPL_STATSDELTA = "274" // IRCnet
RPL_STATSDLINE = "275" // ircu, Ultimate
RPL_USINGSSL = "275" // Bahamut
RPL_WHOISCERTFP = "276" // oftc-hybrid
RPL_STATSRLINE = "276" // ircu
RPL_GLIST = "280" // ircu
RPL_ENDOFGLIST = "281" // ircu
RPL_ACCEPTLIST = "281"
RPL_ENDOFACCEPT = "282"
RPL_JUPELIST = "282" // ircu
RPL_ALIST = "283"
RPL_ENDOFJUPELIST = "283" // ircu
RPL_ENDOFALIST = "284"
RPL_FEATURE = "284" // ircu
RPL_GLIST_HASH = "285"
RPL_CHANINFO_HANDLE = "285" // aircd
RPL_NEWHOSTIS = "285" // QuakeNet
RPL_CHANINFO_USERS = "286" // aircd
RPL_CHKHEAD = "286" // QuakeNet
RPL_CHANINFO_CHOPS = "287" // aircd
RPL_CHANUSER = "287" // QuakeNet
RPL_CHANINFO_VOICES = "288" // aircd
RPL_PATCHHEAD = "288" // QuakeNet
RPL_CHANINFO_AWAY = "289" // aircd
RPL_PATCHCON = "289" // QuakeNet
RPL_CHANINFO_OPERS = "290" // aircd
RPL_HELPHDR = "290" // Unreal
RPL_DATASTR = "290" // QuakeNet
RPL_CHANINFO_BANNED = "291" // aircd
RPL_HELPOP = "291" // Unreal
RPL_ENDOFCHECK = "291" // QuakeNet
RPL_CHANINFO_BANS = "292" // aircd
RPL_HELPTLR = "292" // Unreal
ERR_SEARCHNOMATCH = "292" // Nefarious
RPL_CHANINFO_INVITE = "293" // aircd
RPL_HELPHLP = "293" // Unreal
RPL_CHANINFO_INVITES = "294" // aircd
RPL_HELPFWD = "294" // Unreal
RPL_CHANINFO_KICK = "295" // aircd
RPL_HELPIGN = "295" // Unreal
RPL_CHANINFO_KICKS = "296" // aircd
RPL_END_CHANINFO = "299" // aircd
RPL_TEXT = "304" // irc2?
RPL_USERIP = "307"
RPL_WHOISREGNICK = "307" // Bahamut, Unreal
RPL_SUSERHOST = "307" // AustHex
RPL_NOTIFYACTION = "308" // aircd
RPL_WHOISADMIN = "308" // Bahamut
RPL_RULESSTART = "308" // Unreal
RPL_NICKTRACE = "309" // aircd
RPL_WHOISSADMIN = "309" // Bahamut
RPL_ENDOFRULES = "309" // Unreal
RPL_WHOISHELPER = "309" // AustHex
RPL_WHOISSVCMSG = "310" // Bahamut
RPL_WHOISHELPOP = "310" // Unreal
RPL_WHOISSERVICE = "310" // AustHex
RPL_WHOISPRIVDEAF = "316" // Nefarious
RPL_WHOISVIRT = "320" // AustHex
RPL_WHOIS_HIDDEN = "320" // Anothernet
RPL_WHOISSPECIAL = "320" // Unreal
RPL_CHANNELPASSIS = "325"
RPL_WHOISWEBIRC = "325" // Nefarious
RPL_NOCHANPASS = "326"
RPL_CHPASSUNKNOWN = "327"
RPL_WHOISHOST = "327" // rusnet-ircd
RPL_CHANNEL_URL = "328" // Bahamut, AustHex
RPL_CREATIONTIME = "329" // Bahamut
RPL_WHOWAS_TIME = "330"
RPL_WHOISACCOUNT = "330" // ircu
RPL_TOPICWHOTIME = "333" // ircu
RPL_LISTUSAGE = "334" // ircu
RPL_COMMANDSYNTAX = "334" // Bahamut
RPL_LISTSYNTAX = "334" // Unreal
RPL_WHOISBOT = "335" // Unreal
RPL_WHOISTEXT = "335" // Hybrid
RPL_WHOISACCOUNTONLY = "335" // Nefarious
RPL_INVITELIST = "336" // Hybrid
RPL_WHOISBOT = "336" // Nefarious
RPL_ENDOFINVITELIST = "337" // Hybrid
RPL_WHOISTEXT = "337" // Hybrid?
RPL_CHANPASSOK = "338"
RPL_WHOISACTUALLY = "338" // ircu, Bahamut
RPL_BADCHANPASS = "339"
RPL_WHOISMARKS = "339" // Nefarious
RPL_USERIP = "340" // ircu
RPL_WHOISKILL = "343" // Nefarious
RPL_WHOISCOUNTRY = "344" // InspIRCd 3.0
RPL_INVITED = "345" // GameSurge
RPL_WHOISGATEWAY = "350" // InspIRCd 3.0
RPL_WHOSPCRPL = "354" // ircu
RPL_NAMREPLY_ = "355" // QuakeNet
RPL_MAP = "357" // AustHex
RPL_MAPMORE = "358" // AustHex
RPL_MAPEND = "359" // AustHex
RPL_KICKEXPIRED = "377" // aircd
RPL_BANEXPIRED = "378" // aircd
RPL_WHOISHOST = "378" // Unreal
RPL_KICKLINKED = "379" // aircd
RPL_WHOISMODES = "379" // Unreal
RPL_BANLINKED = "380" // aircd
RPL_YOURHELPER = "380" // AustHex
RPL_NOTOPERANYMORE = "385" // AustHex, Hybrid, Unreal
RPL_QLIST = "386" // Unreal
RPL_IRCOPS = "386" // Ultimate
RPL_IRCOPSHEADER = "386" // Nefarious
RPL_ENDOFQLIST = "387" // Unreal
RPL_ENDOFIRCOPS = "387" // Ultimate
RPL_IRCOPS = "387" // Nefarious
RPL_ALIST = "388" // Unreal
RPL_ENDOFIRCOPS = "388" // Nefarious
RPL_ENDOFALIST = "389" // Unreal
RPL_TIME = "391" // ircu
RPL_TIME = "391" // bdq-ircd
RPL_TIME = "391"
RPL_VISIBLEHOST = "396" // Hybrid
RPL_CLONES = "399" // InspIRCd 3.0
ERR_UNKNOWNERROR = "400"
ERR_NOCOLORSONCHAN = "408" // Bahamut
ERR_NOCTRLSONCHAN = "408" // Hybrid
ERR_TOOMANYMATCHES = "416" // IRCnet
ERR_QUERYTOOLONG = "416" // ircu
ERR_INPUTTOOLONG = "417" // ircu
ERR_LENGTHTRUNCATED = "419" // aircd
ERR_AMBIGUOUSCOMMAND = "420" // InspIRCd
ERR_NOOPERMOTD = "425" // Unreal
ERR_TOOMANYAWAY = "429" // Bahamut
ERR_EVENTNICKCHANGE = "430" // AustHex
ERR_SERVICENAMEINUSE = "434" // AustHex?
ERR_NORULES = "434" // Unreal, Ultimate
ERR_SERVICECONFUSED = "435" // Unreal
ERR_BANONCHAN = "435" // Bahamut
ERR_BANNICKCHANGE = "437" // ircu
ERR_NICKTOOFAST = "438" // ircu
ERR_DEAD = "438" // IRCnet
ERR_TARGETTOOFAST = "439" // ircu
ERR_SERVICESDOWN = "440" // Bahamut, Unreal
ERR_NONICKCHANGE = "447" // Unreal
ERR_FORBIDDENCHANNEL = "448" // Unreal
ERR_NOTIMPLEMENTED = "449" // Undernet
ERR_IDCOLLISION = "452"
ERR_NICKLOST = "453"
ERR_HOSTILENAME = "455" // Unreal
ERR_ACCEPTFULL = "456"
ERR_ACCEPTEXIST = "457"
ERR_ACCEPTNOT = "458"
ERR_NOHIDING = "459" // Unreal
ERR_NOTFORHALFOPS = "460" // Unreal
ERR_INVALIDUSERNAME = "468" // ircu
ERR_ONLYSERVERSCANCHANGE = "468" // Bahamut, Unreal
ERR_NOCODEPAGE = "468" // rusnet-ircd
ERR_LINKSET = "469" // Unreal
ERR_LINKCHANNEL = "470" // Unreal
ERR_KICKEDFROMCHAN = "470" // aircd
ERR_7BIT = "470" // rusnet-ircd
ERR_NEEDREGGEDNICK = "477" // Bahamut, ircu, Unreal
ERR_BADCHANNAME = "479" // Hybrid
ERR_LINKFAIL = "479" // Unreal
ERR_NOCOLOR = "479" // rusnet-ircd
ERR_NOULINE = "480" // AustHex
ERR_CANNOTKNOCK = "480" // Unreal
ERR_THROTTLE = "480" // Ratbox
ERR_NOWALLOP = "480" // rusnet-ircd
ERR_ISCHANSERVICE = "484" // Undernet
ERR_DESYNC = "484" // Bahamut, Hybrid, PTlink
ERR_ATTACKDENY = "484" // Unreal
ERR_KILLDENY = "485" // Unreal
ERR_CANTKICKADMIN = "485" // PTlink
ERR_ISREALSERVICE = "485" // QuakeNet
ERR_CHANBANREASON = "485" // Hybrid
ERR_NONONREG = "486" // Unreal?
ERR_HTMDISABLED = "486" // Unreal
ERR_ACCOUNTONLY = "486" // QuakeNet
ERR_RLINED = "486" // rusnet-ircd
ERR_CHANTOORECENT = "487" // IRCnet
ERR_MSGSERVICES = "487" // Bahamut
ERR_NOTFORUSERS = "487" // Unreal?
ERR_NONONSSL = "487" // ChatIRCd
ERR_TSLESSCHAN = "488" // IRCnet
ERR_HTMDISABLED = "488" // Unreal?
ERR_NOSSL = "488" // Bahamut
ERR_SECUREONLYCHAN = "489" // Unreal
ERR_VOICENEEDED = "489" // Undernet
ERR_ALLMUSTSSL = "490" // InspIRCd
ERR_NOSWEAR = "490" // Unreal
ERR_NOCTCP = "492" // Hybrid / Unreal?
ERR_CANNOTSENDTOUSER = "492" // Charybdis?
ERR_NOSHAREDCHAN = "493" // Bahamut
ERR_NOFEATURE = "493" // ircu
ERR_BADFEATVALUE = "494" // ircu
ERR_OWNMODE = "494" // Bahamut, charybdis?
ERR_BADLOGTYPE = "495" // ircu
ERR_BADLOGSYS = "496" // ircu
ERR_BADLOGVALUE = "497" // ircu
ERR_ISOPERLCHAN = "498" // ircu
ERR_CHANOWNPRIVNEEDED = "499" // Unreal
ERR_TOOMANYJOINS = "500" // Unreal?
ERR_NOREHASHPARAM = "500" // rusnet-ircd
ERR_CANNOTSETMODER = "500" // InspIRCd
ERR_UNKNOWNSNOMASK = "501" // InspIRCd
ERR_USERNOTONSERV = "504"
ERR_SILELISTFULL = "511" // ircu
ERR_TOOMANYWATCH = "512" // Bahamut
ERR_NOSUCHGLINE = "512" // ircu
ERR_BADPING = "513" // ircu
ERR_TOOMANYDCC = "514" // Bahamut
ERR_NOSUCHJUPE = "514" // irch
ERR_BADEXPIRE = "515" // ircu
ERR_DONTCHEAT = "516" // ircu
ERR_DISABLED = "517" // ircu
ERR_NOINVITE = "518" // Unreal
ERR_LONGMASK = "518" // ircu
ERR_ADMONLY = "519" // Unreal
ERR_TOOMANYUSERS = "519" // ircu
ERR_OPERONLY = "520" // Unreal
ERR_MASKTOOWIDE = "520" // ircu
ERR_LISTSYNTAX = "521" // Bahamut
ERR_NOSUCHGLINE = "521" // Nefarious
ERR_WHOSYNTAX = "522" // Bahamut
ERR_WHOLIMEXCEED = "523" // Bahamut
ERR_QUARANTINED = "524" // ircu
ERR_OPERSPVERIFY = "524" // Unreal
ERR_HELPNOTFOUND = "524" // Hybrid
ERR_INVALIDKEY = "525" // ircu
ERR_CANTSENDTOUSER = "531" // InspIRCd
ERR_BADHOSTMASK = "550" // QuakeNet
ERR_HOSTUNAVAIL = "551" // QuakeNet
ERR_USINGSLINE = "552" // QuakeNet
ERR_STATSSLINE = "553" // QuakeNet
ERR_NOTLOWEROPLEVEL = "560" // ircu
ERR_NOTMANAGER = "561" // ircu
ERR_CHANSECURED = "562" // ircu
ERR_UPASSSET = "563" // ircu
ERR_UPASSNOTSET = "564" // ircu
ERR_NOMANAGER = "566" // ircu
ERR_UPASS_SAME_APASS = "567" // ircu
ERR_LASTERROR = "568" // ircu
RPL_NOOMOTD = "568" // Nefarious
RPL_REAWAY = "597" // Unreal
RPL_GONEAWAY = "598" // Unreal
RPL_NOTAWAY = "599" // Unreal
RPL_LOGON = "600" // Bahamut, Unreal
RPL_LOGOFF = "601" // Bahamut, Unreal
RPL_WATCHOFF = "602" // Bahamut, Unreal
RPL_WATCHSTAT = "603" // Bahamut, Unreal
RPL_NOWON = "604" // Bahamut, Unreal
RPL_NOWOFF = "605" // Bahamut, Unreal
RPL_WATCHLIST = "606" // Bahamut, Unreal
RPL_ENDOFWATCHLIST = "607" // Bahamut, Unreal
RPL_WATCHCLEAR = "608" // Ultimate
RPL_NOWISAWAY = "609" // Unreal
RPL_MAPMORE = "610" // Unreal
RPL_ISOPER = "610" // Ultimate
RPL_ISLOCOP = "611" // Ultimate
RPL_ISNOTOPER = "612" // Ultimate
RPL_ENDOFISOPER = "613" // Ultimate
RPL_MAPMORE = "615" // PTlink
RPL_WHOISMODES = "615" // Ultimate
RPL_WHOISHOST = "616" // Ultimate
RPL_WHOISSSLFP = "617" // Nefarious
RPL_DCCSTATUS = "617" // Bahamut
RPL_WHOISBOT = "617" // Ultimate
RPL_DCCLIST = "618" // Bahamut
RPL_ENDOFDCCLIST = "619" // Bahamut
RPL_WHOWASHOST = "619" // Ultimate
RPL_DCCINFO = "620" // Bahamut
RPL_RULESSTART = "620" // Ultimate
RPL_RULES = "621" // Ultimate
RPL_ENDOFRULES = "622" // Ultimate
RPL_MAPMORE = "623" // Ultimate
RPL_OMOTDSTART = "624" // Ultimate
RPL_OMOTD = "625" // Ultimate
RPL_ENDOFOMOTD = "626" // Ultimate
RPL_SETTINGS = "630" // Ultimate
RPL_ENDOFSETTINGS = "631" // Ultimate
RPL_SYNTAX = "650" // InspIRCd 3.0
RPL_CHANNELSMSG = "651" // InspIRCd 3.0
RPL_WHOWASIP = "652" // InspIRCd 3.0
RPL_UNINVITED = "653" // InspIRCd 3.0
RPL_SPAMCMDFWD = "659" // Unreal
RPL_WHOISSECURE = "671" // Unreal
RPL_UNKNOWNMODES = "672" // Ithildin
RPL_WHOISREALIP = "672" // Rizon
RPL_CANNOTSETMODES = "673" // Ithildin
RPL_WHOISYOURID = "674" // ChatIRCd
RPL_LANGUAGES = "690" // Unreal?
ERR_INVALIDMODEPARAM = "696" // InspIRCd 3.0
ERR_LISTMODEALREADYSET = "697" // InspIRCd 3.0
ERR_LISTMODENOTSET = "698" // InspIRCd 3.0
RPL_COMMANDS = "700" // InspIRCd 3.0
RPL_COMMANDSEND = "701" // InspIRCd 3.0
RPL_MODLIST = "702" // RatBox
RPL_ENDOFMODLIST = "703" // RatBox
RPL_HELPSTART = "704" // RatBox
RPL_HELPTXT = "705" // RatBox
RPL_ENDOFHELP = "706" // RatBox
ERR_TARGCHANGE = "707" // RatBox
RPL_ETRACEFULL = "708" // RatBox
RPL_ETRACE = "709" // RatBox
RPL_KNOCK = "710" // RatBox
RPL_KNOCKDLVR = "711" // RatBox
ERR_TOOMANYKNOCK = "712" // RatBox
ERR_CHANOPEN = "713" // RatBox
ERR_KNOCKONCHAN = "714" // RatBox
ERR_KNOCKDISABLED = "715" // RatBox
ERR_TOOMANYINVITE = "715" // Hybrid
RPL_INVITETHROTTLE = "715" // Rizon
RPL_TARGUMODEG = "716" // RatBox
RPL_TARGNOTIFY = "717" // RatBox
RPL_UMODEGMSG = "718" // RatBox
RPL_OMOTDSTART = "720" // RatBox
RPL_OMOTD = "721" // RatBox
RPL_ENDOFOMOTD = "722" // RatBox
ERR_NOPRIVS = "723" // RatBox
RPL_TESTMASK = "724" // RatBox
RPL_TESTLINE = "725" // RatBox
RPL_NOTESTLINE = "726" // RatBox
RPL_TESTMASKGECOS = "727" // RatBox
RPL_QUIETLIST = "728" // Charybdis
RPL_ENDOFQUIETLIST = "729" // Charybdis
RPL_RSACHALLENGE2 = "740" // RatBox
RPL_ENDOFRSACHALLENGE2 = "741" // RatBox
ERR_MLOCKRESTRICTED = "742" // Charybdis
ERR_INVALIDBAN = "743" // Charybdis
ERR_TOPICLOCK = "744" // InspIRCd?
RPL_SCANMATCHED = "750" // RatBox
RPL_SCANUMODES = "751" // RatBox
RPL_ETRACEEND = "759" // irc2.11
RPL_XINFO = "771" // Ithildin
RPL_XINFOSTART = "773" // Ithildin
RPL_XINFOEND = "774" // Ithildin
RPL_CHECK = "802" // InspIRCd 3.0
RPL_OTHERUMODEIS = "803" // InspIRCd 3.0
RPL_OTHERSNOMASKIS = "804" // InspIRCd 3.0
ERR_BADCHANNEL = "926" // InspIRCd
ERR_INVALIDWATCHNICK = "942" // InspIRCd
RPL_IDLETIMESET = "944" // InspIRCd
RPL_NICKLOCKOFF = "945" // InspIRCd
ERR_NICKNOTLOCKED = "946" // InspIRCd
RPL_NICKLOCKON = "947" // InspIRCd
ERR_INVALIDIDLETIME = "948" // InspIRCd
RPL_UNSILENCED = "950" // InspIRCd
RPL_SILENCED = "951" // InspIRCd
ERR_NOTSILENCED = "952" // InspIRCd
RPL_ENDOFPROPLIST = "960" // InspIRCd
RPL_PROPLIST = "961" // InspIRCd
ERR_CANNOTDOCOMMAND = "972" // Unreal
ERR_CANTUNLOADMODULE = "972" // InspIRCd
RPL_UNLOADEDMODULE = "973" // InspIRCd
ERR_CANNOTCHANGECHANMODE = "974" // Unreal
ERR_CANTLOADMODULE = "974" // InspIRCd
RPL_LOADEDMODULE = "975" // InspIRCd
ERR_LASTERROR = "975" // Nefarious
RPL_SERVLOCKON = "988" // InspIRCd
RPL_SERVLOCKOFF = "989" // InspIRCd
RPL_DCCALLOWSTART = "990" // InspIRCd
RPL_DCCALLOWLIST = "991" // InspIRCd
RPL_DCCALLOWEND = "992" // InspIRCd
RPL_DCCALLOWTIMED = "993" // InspIRCd
RPL_DCCALLOWPERMANENT = "994" // InspIRCd
RPL_DCCALLOWREMOVED = "995" // InspIRCd
ERR_DCCALLOWINVALID = "996" // InspIRCd
RPL_DCCALLOWEXPIRED = "997" // InspIRCd
ERR_UNKNOWNDCCALLOWCMD = "998" // InspIRCd
ERR_NUMERIC_ERR = "999" // Bahamut
//*/
// Obsolete
/*
RPL_STATMEM = "010" // ircu
RPL_STATSZLINE = "225" // Bahamut
RPL_MAPUSERS = "270" // InspIRCd 2.0
RPL_VCHANEXIST = "276" // Hybrid
RPL_VCHANLIST = "277" // Hybrid
RPL_VCHANHELP = "278" // Hybrid 7.0?
RPL_CHANNELMLOCKIS = "325" // sorircd
RPL_WHOWASREAL = "360" // Charybdis
RPL_SPAM = "377" // AustHex
RPL_MOTD = "378" // AustHex
RPL_WHOWASIP = "379" // InspIRCd 2.0
RPL_RSACHALLENGE = "386" // Hybrid
ERR_SSLONLYCHAN = "480" // Hybrid
ERR_BANNEDNICK = "485" // Ratbox
ERR_DELAYREJOIN = "495" // InspIRCd 2.0
ERR_GHOSTEDCLIENT = "503" // Hybrid
ERR_VWORLDWARN = "503" // AustHex
ERR_INVALID_ERROR = "514" // ircu
ERR_WHOTRUNC = "520" // AustHex
ERR_REMOTEPFX = "525" // CAPAB USERCMDPFX
ERR_PFXUNROUTABLE = "526" // CAPAB USERCMDPFX
RPL_DUMPING = "640" // Unreal
RPL_DUMPRPL = "641" // Unreal
RPL_EODUMP = "642" // Unreal
RPL_COMMANDS = "702" // InspIRCd 2.0
RPL_COMMANDSEND = "703" // InspIRCd 2.0
ERR_WORDFILTERED = "936" // InspIRCd
ERR_ALREADYCHANFILTERED = "937" // InspIRCd 2.0
ERR_NOSUCHCHANFILTER = "938" // InspIRCd 2.0
ERR_CHANFILTERFULL = "939" // InspIRCd 2.0
RPL_DCCALLOWHELP = "998" // InspIRCd
RPL_ENDOFDCCALLOWHELP = "999" // InspIRCd 2.0
//*/
)

403
vendor/gopkg.in/irc.v3/parser.go generated vendored Normal file
View File

@ -0,0 +1,403 @@
package irc
import (
"bytes"
"errors"
"strings"
)
var tagDecodeSlashMap = map[rune]rune{
':': ';',
's': ' ',
'\\': '\\',
'r': '\r',
'n': '\n',
}
var tagEncodeMap = map[rune]string{
';': "\\:",
' ': "\\s",
'\\': "\\\\",
'\r': "\\r",
'\n': "\\n",
}
var (
// ErrZeroLengthMessage is returned when parsing if the input is
// zero-length.
ErrZeroLengthMessage = errors.New("irc: Cannot parse zero-length message")
// ErrMissingDataAfterPrefix is returned when parsing if there is
// no message data after the prefix.
ErrMissingDataAfterPrefix = errors.New("irc: No message data after prefix")
// ErrMissingDataAfterTags is returned when parsing if there is no
// message data after the tags.
ErrMissingDataAfterTags = errors.New("irc: No message data after tags")
// ErrMissingCommand is returned when parsing if there is no
// command in the parsed message.
ErrMissingCommand = errors.New("irc: Missing message command")
)
// TagValue represents the value of a tag.
type TagValue string
// ParseTagValue parses a TagValue from the connection. If you need to
// set a TagValue, you probably want to just set the string itself, so
// it will be encoded properly.
func ParseTagValue(v string) TagValue {
ret := &bytes.Buffer{}
input := bytes.NewBufferString(v)
for {
c, _, err := input.ReadRune()
if err != nil {
break
}
if c == '\\' {
c2, _, err := input.ReadRune()
// If we got a backslash then the end of the tag value, we should
// just ignore the backslash.
if err != nil {
break
}
if replacement, ok := tagDecodeSlashMap[c2]; ok {
ret.WriteRune(replacement)
} else {
ret.WriteRune(c2)
}
} else {
ret.WriteRune(c)
}
}
return TagValue(ret.String())
}
// Encode converts a TagValue to the format in the connection.
func (v TagValue) Encode() string {
ret := &bytes.Buffer{}
for _, c := range v {
if replacement, ok := tagEncodeMap[c]; ok {
ret.WriteString(replacement)
} else {
ret.WriteRune(c)
}
}
return ret.String()
}
// Tags represents the IRCv3 message tags.
type Tags map[string]TagValue
// ParseTags takes a tag string and parses it into a tag map. It will
// always return a tag map, even if there are no valid tags.
func ParseTags(line string) Tags {
ret := Tags{}
tags := strings.Split(line, ";")
for _, tag := range tags {
parts := strings.SplitN(tag, "=", 2)
if len(parts) < 2 {
ret[parts[0]] = ""
continue
}
ret[parts[0]] = ParseTagValue(parts[1])
}
return ret
}
// GetTag is a convenience method to look up a tag in the map.
func (t Tags) GetTag(key string) (string, bool) {
ret, ok := t[key]
return string(ret), ok
}
// Copy will create a new copy of all IRC tags attached to this
// message.
func (t Tags) Copy() Tags {
ret := Tags{}
for k, v := range t {
ret[k] = v
}
return ret
}
// String ensures this is stringable
func (t Tags) String() string {
buf := &bytes.Buffer{}
for k, v := range t {
buf.WriteByte(';')
buf.WriteString(k)
if v != "" {
buf.WriteByte('=')
buf.WriteString(v.Encode())
}
}
// We don't need the first byte because that's an extra ';'
// character.
buf.ReadByte()
return buf.String()
}
// Prefix represents the prefix of a message, generally the user who sent it
type Prefix struct {
// Name will contain the nick of who sent the message, the
// server who sent the message, or a blank string
Name string
// User will either contain the user who sent the message or a blank string
User string
// Host will either contain the host of who sent the message or a blank string
Host string
}
// ParsePrefix takes an identity string and parses it into an
// identity struct. It will always return an Prefix struct and never
// nil.
func ParsePrefix(line string) *Prefix {
// Start by creating an Prefix with nothing but the host
id := &Prefix{
Name: line,
}
uh := strings.SplitN(id.Name, "@", 2)
if len(uh) == 2 {
id.Name, id.Host = uh[0], uh[1]
}
nu := strings.SplitN(id.Name, "!", 2)
if len(nu) == 2 {
id.Name, id.User = nu[0], nu[1]
}
return id
}
// Copy will create a new copy of an Prefix
func (p *Prefix) Copy() *Prefix {
if p == nil {
return nil
}
newPrefix := &Prefix{}
*newPrefix = *p
return newPrefix
}
// String ensures this is stringable
func (p *Prefix) String() string {
buf := &bytes.Buffer{}
buf.WriteString(p.Name)
if p.User != "" {
buf.WriteString("!")
buf.WriteString(p.User)
}
if p.Host != "" {
buf.WriteString("@")
buf.WriteString(p.Host)
}
return buf.String()
}
// Message represents a line parsed from the server
type Message struct {
// Each message can have IRCv3 tags
Tags
// Each message can have a Prefix
*Prefix
// Command is which command is being called.
Command string
// Params are all the arguments for the command.
Params []string
}
// MustParseMessage calls ParseMessage and either returns the message
// or panics if an error is returned.
func MustParseMessage(line string) *Message {
m, err := ParseMessage(line)
if err != nil {
panic(err.Error())
}
return m
}
// ParseMessage takes a message string (usually a whole line) and
// parses it into a Message struct. This will return nil in the case
// of invalid messages.
func ParseMessage(line string) (*Message, error) {
// Trim the line and make sure we have data
line = strings.TrimRight(line, "\r\n")
if len(line) == 0 {
return nil, ErrZeroLengthMessage
}
c := &Message{
Tags: Tags{},
Prefix: &Prefix{},
}
if line[0] == '@' {
loc := strings.Index(line, " ")
if loc == -1 {
return nil, ErrMissingDataAfterTags
}
c.Tags = ParseTags(line[1:loc])
line = line[loc+1:]
}
if line[0] == ':' {
loc := strings.Index(line, " ")
if loc == -1 {
return nil, ErrMissingDataAfterPrefix
}
// Parse the identity, if there was one
c.Prefix = ParsePrefix(line[1:loc])
line = line[loc+1:]
}
// Split out the trailing then the rest of the args. Because
// we expect there to be at least one result as an arg (the
// command) we don't need to special case the trailing arg and
// can just attempt a split on " :"
split := strings.SplitN(line, " :", 2)
c.Params = strings.FieldsFunc(split[0], func(r rune) bool {
return r == ' '
})
// If there are no args, we need to bail because we need at
// least the command.
if len(c.Params) == 0 {
return nil, ErrMissingCommand
}
// If we had a trailing arg, append it to the other args
if len(split) == 2 {
c.Params = append(c.Params, split[1])
}
// Because of how it's parsed, the Command will show up as the
// first arg.
c.Command = strings.ToUpper(c.Params[0])
c.Params = c.Params[1:]
// If there are no params, set it to nil, to make writing tests and other
// things simpler.
if len(c.Params) == 0 {
c.Params = nil
}
return c, nil
}
// Param returns the i'th argument in the Message or an empty string
// if the requested arg does not exist
func (m *Message) Param(i int) string {
if i < 0 || i >= len(m.Params) {
return ""
}
return m.Params[i]
}
// Trailing returns the last argument in the Message or an empty string
// if there are no args
func (m *Message) Trailing() string {
if len(m.Params) < 1 {
return ""
}
return m.Params[len(m.Params)-1]
}
// Copy will create a new copy of an message
func (m *Message) Copy() *Message {
// Create a new message
newMessage := &Message{}
// Copy stuff from the old message
*newMessage = *m
// Copy any IRcv3 tags
newMessage.Tags = m.Tags.Copy()
// Copy the Prefix
newMessage.Prefix = m.Prefix.Copy()
// Copy the Params slice
newMessage.Params = append(make([]string, 0, len(m.Params)), m.Params...)
// Similar to parsing, if Params is empty, set it to nil
if len(newMessage.Params) == 0 {
newMessage.Params = nil
}
return newMessage
}
// String ensures this is stringable
func (m *Message) String() string {
buf := &bytes.Buffer{}
// Write any IRCv3 tags if they exist in the message
if len(m.Tags) > 0 {
buf.WriteByte('@')
buf.WriteString(m.Tags.String())
buf.WriteByte(' ')
}
// Add the prefix if we have one
if m.Prefix != nil && m.Prefix.Name != "" {
buf.WriteByte(':')
buf.WriteString(m.Prefix.String())
buf.WriteByte(' ')
}
// Add the command since we know we'll always have one
buf.WriteString(m.Command)
if len(m.Params) > 0 {
args := m.Params[:len(m.Params)-1]
trailing := m.Params[len(m.Params)-1]
if len(args) > 0 {
buf.WriteByte(' ')
buf.WriteString(strings.Join(args, " "))
}
// If trailing is zero-length, contains a space or starts with
// a : we need to actually specify that it's trailing.
if len(trailing) == 0 || strings.ContainsRune(trailing, ' ') || trailing[0] == ':' {
buf.WriteString(" :")
} else {
buf.WriteString(" ")
}
buf.WriteString(trailing)
}
return buf.String()
}

50
vendor/gopkg.in/irc.v3/utils.go generated vendored Normal file
View File

@ -0,0 +1,50 @@
package irc
import (
"bytes"
"regexp"
)
var maskTranslations = map[byte]string{
'?': ".",
'*': ".*",
}
// MaskToRegex converts an irc mask to a go Regexp for more convenient
// use. This should never return an error, but we have this here just
// in case.
func MaskToRegex(rawMask string) (*regexp.Regexp, error) {
input := bytes.NewBufferString(rawMask)
output := &bytes.Buffer{}
output.WriteByte('^')
for {
c, err := input.ReadByte()
if err != nil {
break
}
if c == '\\' {
c, err = input.ReadByte()
if err != nil {
output.WriteString(regexp.QuoteMeta("\\"))
break
}
if c == '?' || c == '*' || c == '\\' {
output.WriteString(regexp.QuoteMeta(string(c)))
} else {
output.WriteString(regexp.QuoteMeta("\\" + string(c)))
}
} else if trans, ok := maskTranslations[c]; ok {
output.WriteString(trans)
} else {
output.WriteString(regexp.QuoteMeta(string(c)))
}
}
output.WriteByte('$')
return regexp.Compile(output.String())
}

23
vendor/gopkg.in/zeromq/goczmq.v4/.gitignore generated vendored Normal file
View File

@ -0,0 +1,23 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test

17
vendor/gopkg.in/zeromq/goczmq.v4/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,17 @@
language: go
warnings_are_errors: false
addons:
apt:
sources:
- sourceline: 'deb http://download.opensuse.org/repositories/network:/messaging:/zeromq:/git-draft/xUbuntu_12.04/ ./'
key_url: 'http://download.opensuse.org/repositories/network:/messaging:/zeromq:/git-draft/xUbuntu_12.04/Release.key'
packages:
- libsodium-dev
- libczmq-dev
go:
- 1.7.1
script:
- go get -t -v ./...
- go test -v .

15
vendor/gopkg.in/zeromq/goczmq.v4/AUTHORS generated vendored Normal file
View File

@ -0,0 +1,15 @@
Contributors (no particular order)
==================================
Brian Knox
Luna Duclos
Indradhanush Gupta
Armen Baghumian
Ben Aldrich
Jordan Sissel
Nick Bargnesi
Cyrille Verrier
Ben Aldrich
Matthew Campbell
James Reuss
Pieter Hintjens

22
vendor/gopkg.in/zeromq/goczmq.v4/CONTRIBUTING.md generated vendored Normal file
View File

@ -0,0 +1,22 @@
# Contributing to GoCZMQ
The contributors are listed in AUTHORS (add yourself). This project uses the MPL v2 license, see LICENSE.
# Our Process
Before you send a pull request, please familiarize yourself with the [C4.1 Collective Code Construction Contract](http://rfc.zeromq.org/spec:22) process. A quick summary (but please, do read the process document):
* A Pull Request should be described in the form of a problem statement.
* The code included with the pull request should be a proposed solution to that problem.
* The submitted code should adhere to our style guidelines (described below).
* The submitted code should include tests.
* The submitted code should not break any existing tests.
"A Problem" should be one single clear problem. Large complex problems should be broken down into a series of smaller problems when ever possible.
**Please be aware** that GoCZMQ is **not versioned**. We merge to master. We deploy from master. Master is epxected to be working, at all times. We strive to do our very best to never break public API in this library. Changes can be additive, but they can not break the existing API. If a case arises where we need to, we will be loud about it on the ZeroMQ mailing list and try to build consensus among current maintainers that it's necessary. We will be very chagrined about it, and you can poke fun at us a bit.
# Style Guide
* Your code must be formatted with [Gofmt](https://blog.golang.org/go-fmt-your-code)
* Your code should pass [golint](https://github.com/golang/lint). If for some reason it cannot, please provide an explanation.
* Your code should pass [go vet](https://golang.org/cmd/vet/)

362
vendor/gopkg.in/zeromq/goczmq.v4/LICENSE generated vendored Normal file
View File

@ -0,0 +1,362 @@
Mozilla Public License, version 2.0
1. Definitions
1.1. "Contributor"
means each individual or legal entity that creates, contributes to the
creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used by a
Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached the
notice in Exhibit A, the Executable Form of such Source Code Form, and
Modifications of such Source Code Form, in each case including portions
thereof.
1.5. "Incompatible With Secondary Licenses"
means
a. that the initial Contributor has attached the notice described in
Exhibit B to the Covered Software; or
b. that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the terms of
a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in a
separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible, whether
at the time of the initial grant or subsequently, any and all of the
rights conveyed by this License.
1.10. "Modifications"
means any of the following:
a. any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered Software; or
b. any new file in Source Code Form that contains any Covered Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the License,
by the making, using, selling, offering for sale, having made, import,
or transfer of either its Contributions or its Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU Lesser
General Public License, Version 2.1, the GNU Affero General Public
License, Version 3.0, or any later versions of those licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that controls, is
controlled by, or is under common control with You. For purposes of this
definition, "control" means (a) the power, direct or indirect, to cause
the direction or management of such entity, whether by contract or
otherwise, or (b) ownership of more than fifty percent (50%) of the
outstanding shares or beneficial ownership of such entity.
2. License Grants and Conditions
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
a. under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
b. under Patent Claims of such Contributor to make, use, sell, offer for
sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
a. for any code that a Contributor has removed from Covered Software; or
b. for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
c. under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights to
grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
Section 2.1.
3. Responsibilities
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
a. such Covered Software must also be made available in Source Code Form,
as described in Section 3.1, and You must inform recipients of the
Executable Form how they can obtain a copy of such Source Code Form by
reasonable means in a timely manner, at a charge no more than the cost
of distribution to the recipient; and
b. You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter the
recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty, or
limitations of liability) contained within the Source Code Form of the
Covered Software, except that You may alter any license notices to the
extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
If it is impossible for You to comply with any of the terms of this License
with respect to some or all of the Covered Software due to statute,
judicial order, or regulation then You must: (a) comply with the terms of
this License to the maximum extent possible; and (b) describe the
limitations and the code they affect. Such description must be placed in a
text file included with all distributions of the Covered Software under
this License. Except to the extent prohibited by statute or regulation,
such description must be sufficiently detailed for a recipient of ordinary
skill to be able to understand it.
5. Termination
5.1. The rights granted under this License will terminate automatically if You
fail to comply with any of its terms. However, if You become compliant,
then the rights granted under this License from a particular Contributor
are reinstated (a) provisionally, unless and until such Contributor
explicitly and finally terminates Your grants, and (b) on an ongoing
basis, if such Contributor fails to notify You of the non-compliance by
some reasonable means prior to 60 days after You have come back into
compliance. Moreover, Your grants from a particular Contributor are
reinstated on an ongoing basis if such Contributor notifies You of the
non-compliance by some reasonable means, this is the first time You have
received notice of non-compliance with this License from such
Contributor, and You become compliant prior to 30 days after Your receipt
of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
license agreements (excluding distributors and resellers) which have been
validly granted by You or Your distributors under this License prior to
termination shall survive termination.
6. Disclaimer of Warranty
Covered Software is provided under this License on an "as is" basis,
without warranty of any kind, either expressed, implied, or statutory,
including, without limitation, warranties that the Covered Software is free
of defects, merchantable, fit for a particular purpose or non-infringing.
The entire risk as to the quality and performance of the Covered Software
is with You. Should any Covered Software prove defective in any respect,
You (not any Contributor) assume the cost of any necessary servicing,
repair, or correction. This disclaimer of warranty constitutes an essential
part of this License. No use of any Covered Software is authorized under
this License except under this disclaimer.
7. Limitation of Liability
Under no circumstances and under no legal theory, whether tort (including
negligence), contract, or otherwise, shall any Contributor, or anyone who
distributes Covered Software as permitted above, be liable to You for any
direct, indirect, special, incidental, or consequential damages of any
character including, without limitation, damages for lost profits, loss of
goodwill, work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses, even if such party shall have been
informed of the possibility of such damages. This limitation of liability
shall not apply to liability for death or personal injury resulting from
such party's negligence to the extent applicable law prohibits such
limitation. Some jurisdictions do not allow the exclusion or limitation of
incidental or consequential damages, so this exclusion and limitation may
not apply to You.
8. Litigation
Any litigation relating to this License may be brought only in the courts
of a jurisdiction where the defendant maintains its principal place of
business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions. Nothing
in this Section shall prevent a party's ability to bring cross-claims or
counter-claims.
9. Miscellaneous
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides that
the language of a contract shall be construed against the drafter shall not
be used to construe this License against a Contributor.
10. Versions of the License
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses If You choose to distribute Source Code Form that is
Incompatible With Secondary Licenses under the terms of this version of
the License, the notice described in Exhibit B of this License must be
attached.
Exhibit A - Source Code Form License Notice
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular file,
then You may include the notice in a location (such as a LICENSE file in a
relevant directory) where a recipient would be likely to look for such a
notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
This Source Code Form is "Incompatible
With Secondary Licenses", as defined by
the Mozilla Public License, v. 2.0.

18
vendor/gopkg.in/zeromq/goczmq.v4/Makefile generated vendored Normal file
View File

@ -0,0 +1,18 @@
build: format clean test
go build ./...
test: get
go test -v .
bench: get
go test -v -bench . ./...
get:
go get -t -v ./...
format:
find . -name \*.go -type f -exec gofmt -w {} \;
clean:
.PHONY: clean build

261
vendor/gopkg.in/zeromq/goczmq.v4/README.md generated vendored Normal file
View File

@ -0,0 +1,261 @@
# goczmq [![Build Status](https://travis-ci.org/zeromq/goczmq.svg?branch=master)](https://travis-ci.org/zeromq/goczmq) [![Doc Status](https://godoc.org/github.com/zeromq/goczmq?status.png)](https://godoc.org/github.com/zeromq/goczmq)
## Introduction
A golang interface to the [CZMQ v4.2](http://czmq.zeromq.org) API.
## Install
### Dependencies
* [libsodium](https://github.com/jedisct1/libsodium)
* [libzmq](https://github.com/zeromq/libzmq)
* [czmq](https://github.com/zeromq/czmq)
### For CZMQ master
```
go get github.com/zeromq/goczmq
```
#### A Note on Build Tags
The CZMQ library includes experimental classes that are not built by default, but can be built
by passing `--enable-drafts` to configure. Support for these draft classes are being added
to goczmq. To build these features against a CZMQ that has been compiled with `--enable-drafts`,
use `go build -tags draft`.
### For CMZQ = 4.0
```
go get gopkg.in/zeromq/goczmq.v4
```
### For CZMQ Before 4.0
```
go get gopkg.in/zeromq/goczmq.v1
```
## Usage
### Direct CZMQ Sock API
#### Example
```go
package main
import (
"log"
"github.com/zeromq/goczmq"
)
func main() {
// Create a router socket and bind it to port 5555.
router, err := goczmq.NewRouter("tcp://*:5555")
if err != nil {
log.Fatal(err)
}
defer router.Destroy()
log.Println("router created and bound")
// Create a dealer socket and connect it to the router.
dealer, err := goczmq.NewDealer("tcp://127.0.0.1:5555")
if err != nil {
log.Fatal(err)
}
defer dealer.Destroy()
log.Println("dealer created and connected")
// Send a 'Hello' message from the dealer to the router.
// Here we send it as a frame ([]byte), with a FlagNone
// flag to indicate there are no more frames following.
err = dealer.SendFrame([]byte("Hello"), goczmq.FlagNone)
if err != nil {
log.Fatal(err)
}
log.Println("dealer sent 'Hello'")
// Receve the message. Here we call RecvMessage, which
// will return the message as a slice of frames ([][]byte).
// Since this is a router socket that support async
// request / reply, the first frame of the message will
// be the routing frame.
request, err := router.RecvMessage()
if err != nil {
log.Fatal(err)
}
log.Printf("router received '%s' from '%v'", request[1], request[0])
// Send a reply. First we send the routing frame, which
// lets the dealer know which client to send the message.
// The FlagMore flag tells the router there will be more
// frames in this message.
err = router.SendFrame(request[0], goczmq.FlagMore)
if err != nil {
log.Fatal(err)
}
log.Printf("router sent 'World'")
// Next send the reply. The FlagNone flag tells the router
// that this is the last frame of the message.
err = router.SendFrame([]byte("World"), goczmq.FlagNone)
if err != nil {
log.Fatal(err)
}
// Receive the reply.
reply, err := dealer.RecvMessage()
if err != nil {
log.Fatal(err)
}
log.Printf("dealer received '%s'", string(reply[0]))
}
```
#### Output
```
2015/05/26 21:52:52 router created and bound
2015/05/26 21:52:52 dealer created and connected
2015/05/26 21:52:52 dealer sent 'Hello'
2015/05/26 21:52:52 router received 'Hello' from '[0 103 84 189 175]'
2015/05/26 21:52:52 router sent 'World'
2015/05/26 21:52:52 dealer received 'World'
```
### io.ReadWriter support
#### Example
```go
package main
import (
"log"
"github.com/zeromq/goczmq"
)
func main() {
// Create a router socket and bind it to port 5555.
router, err := goczmq.NewRouter("tcp://*:5555")
if err != nil {
log.Fatal(err)
}
defer router.Destroy()
log.Println("router created and bound")
// Create a dealer socket and connect it to the router.
dealer, err := goczmq.NewDealer("tcp://127.0.0.1:5555")
if err != nil {
log.Fatal(err)
}
defer dealer.Destroy()
log.Println("dealer created and connected")
// Send a 'Hello' message from the dealer to the router,
// using the io.Write interface
n, err := dealer.Write([]byte("Hello"))
if err != nil {
log.Fatal(err)
}
log.Printf("dealer sent %d byte message 'Hello'\n", n)
// Make a byte slice and pass it to the router
// Read interface. When using the ReadWriter
// interface with a router socket, the router
// caches the routing frames internally in a
// FIFO and uses them transparently when
// sending replies.
buf := make([]byte, 16386)
n, err = router.Read(buf)
if err != nil {
log.Fatal(err)
}
log.Printf("router received '%s'\n", buf[:n])
// Send a reply.
n, err = router.Write([]byte("World"))
if err != nil {
log.Fatal(err)
}
log.Printf("router sent %d byte message 'World'\n", n)
// Receive the reply, reusing the previous buffer.
n, err = dealer.Read(buf)
if err != nil {
log.Fatal(err)
}
log.Printf("dealer received '%s'", string(buf[:n]))
}
```
#### Output
```
2015/05/26 21:54:10 router created and bound
2015/05/26 21:54:10 dealer created and connected
2015/05/26 21:54:10 dealer sent 5 byte message 'Hello'
2015/05/26 21:54:10 router received 'Hello'
2015/05/26 21:54:10 router sent 5 byte message 'World'
2015/05/26 21:54:10 dealer received 'World'
```
### Thread safe channel interface
#### Example
```go
package main
import (
"log"
"github.com/zeromq/goczmq"
)
func main() {
// Create a router channeler and bind it to port 5555.
// A channeler provides a thread safe channel interface
// to a *Sock
router := goczmq.NewRouterChanneler("tcp://*:5555")
defer router.Destroy()
log.Println("router created and bound")
// Create a dealer channeler and connect it to the router.
dealer := goczmq.NewDealerChanneler("tcp://127.0.0.1:5555")
defer dealer.Destroy()
log.Println("dealer created and connected")
// Send a 'Hello' message from the dealer to the router.
dealer.SendChan <- [][]byte{[]byte("Hello")}
log.Println("dealer sent 'Hello'")
// Receve the message as a [][]byte. Since this is
// a router, the first frame of the message wil
// be the routing frame.
request := <-router.RecvChan
log.Printf("router received '%s' from '%v'", request[1], request[0])
// Send a reply. First we send the routing frame, which
// lets the dealer know which client to send the message.
router.SendChan <- [][]byte{request[0], []byte("World")}
log.Printf("router sent 'World'")
// Receive the reply.
reply := <-dealer.RecvChan
log.Printf("dealer received '%s'", string(reply[0]))
}
```
#### Output
```
2015/05/26 21:56:43 router created and bound
2015/05/26 21:56:43 dealer created and connected
2015/05/26 21:56:43 dealer sent 'Hello'
2015/05/26 21:56:43 received 'Hello' from '[0 12 109 153 35]'
2015/05/26 21:56:43 router sent 'World'
2015/05/26 21:56:43 dealer received 'World'
```
## GoDoc
[godoc](https://godoc.org/github.com/zeromq/goczmq)
## See Also
* [Peter Kleiweg's](https://github.com/pebbe) [zmq4](https://github.com/pebbe/zmq4) bindings
## License
This project uses the MPL v2 license, see LICENSE

140
vendor/gopkg.in/zeromq/goczmq.v4/auth.go generated vendored Normal file
View File

@ -0,0 +1,140 @@
package goczmq
/*
#include "czmq.h"
zactor_t *Auth_new () {
zactor_t *auth = zactor_new(zauth, NULL); return auth;
}
*/
import "C"
import (
"unsafe"
)
// Auth wraps the CZMQ zauth actor. It handles authentication
// for all incoming connections. It allows whitelisting and
// blackisting peers based on IP address and support
// PLAIN and CURVE authentication policies.
type Auth struct {
zactorT *C.struct__zactor_t
}
// NewAuth creates a new Auth actor.
func NewAuth() *Auth {
z := &Auth{}
z.zactorT = C.Auth_new()
return z
}
// Verbose sets the auth actor to log information to stdout.
func (a *Auth) Verbose() error {
cmd := C.CString("VERBOSE")
defer C.free(unsafe.Pointer(cmd))
rc := C.zstr_send(unsafe.Pointer(a.zactorT), cmd)
if rc == -1 {
return ErrActorCmd
}
C.zsock_wait(unsafe.Pointer(a.zactorT))
return nil
}
// Deny adds an address to a socket's deny list
func (a *Auth) Deny(address string) error {
cmd := C.CString("DENY")
defer C.free(unsafe.Pointer(cmd))
cAddress := C.CString(address)
defer C.free(unsafe.Pointer(cAddress))
rc := C.zstr_sendm(unsafe.Pointer(a.zactorT), cmd)
if rc == -1 {
return ErrActorCmd
}
rc = C.zstr_send(unsafe.Pointer(a.zactorT), cAddress)
if rc == -1 {
return ErrActorCmd
}
C.zsock_wait(unsafe.Pointer(a.zactorT))
return nil
}
// Allow removes a previous Deny
func (a *Auth) Allow(address string) error {
cmd := C.CString("ALLOW")
defer C.free(unsafe.Pointer(cmd))
cAddress := C.CString(address)
defer C.free(unsafe.Pointer(cAddress))
rc := C.zstr_sendm(unsafe.Pointer(a.zactorT), cmd)
if rc == -1 {
return ErrActorCmd
}
rc = C.zstr_send(unsafe.Pointer(a.zactorT), cAddress)
if rc == -1 {
return ErrActorCmd
}
C.zsock_wait(unsafe.Pointer(a.zactorT))
return nil
}
// Curve sets auth method to curve
func (a *Auth) Curve(allowed string) error {
cmd := C.CString("CURVE")
defer C.free(unsafe.Pointer(cmd))
cAllowed := C.CString(allowed)
defer C.free(unsafe.Pointer(cAllowed))
rc := C.zstr_sendm(unsafe.Pointer(a.zactorT), cmd)
if rc == -1 {
return ErrActorCmd
}
rc = C.zstr_send(unsafe.Pointer(a.zactorT), cAllowed)
if rc == -1 {
return ErrActorCmd
}
C.zsock_wait(unsafe.Pointer(a.zactorT))
return nil
}
// Plain sets auth method to plain
func (a *Auth) Plain(directory string) error {
cmd := C.CString("PLAIN")
defer C.free(unsafe.Pointer(cmd))
cDirectory := C.CString(directory)
defer C.free(unsafe.Pointer(cDirectory))
rc := C.zstr_sendm(unsafe.Pointer(a.zactorT), cmd)
if rc == -1 {
return ErrActorCmd
}
rc = C.zstr_send(unsafe.Pointer(a.zactorT), cDirectory)
if rc == -1 {
return ErrActorCmd
}
C.zsock_wait(unsafe.Pointer(a.zactorT))
return nil
}
// Destroy destroys the auth actor.
func (a *Auth) Destroy() {
C.zactor_destroy(&a.zactorT)
}

162
vendor/gopkg.in/zeromq/goczmq.v4/beacon.go generated vendored Normal file
View File

@ -0,0 +1,162 @@
package goczmq
/*
#include "czmq.h"
zactor_t *Beacon_new () {
zactor_t *beacon = zactor_new(zbeacon, NULL); return beacon;
}
int Beacon_publish(void *actor, void *data, int size, int interval) {
return zsock_send(actor, "sbi", "PUBLISH", (byte*)data, size, interval);
}
*/
import "C"
import (
"strconv"
"unsafe"
)
// Beacon wraps the CZMQ beacon actor. It implements a
// peer-to-peer discovery service for local networks. Beacons
// can broadcast and receive UDPv4 service broadcasts.
type Beacon struct {
zactorT *C.struct__zactor_t
}
// NewBeacon creates a new Beacon instance.
func NewBeacon() *Beacon {
z := &Beacon{}
z.zactorT = C.Beacon_new()
return z
}
// Verbose sets the beacon to log information to stdout.
func (b *Beacon) Verbose() error {
cmd := C.CString("VERBOSE")
defer C.free(unsafe.Pointer(cmd))
rc := C.zstr_send(unsafe.Pointer(b.zactorT), cmd)
if rc == -1 {
return ErrActorCmd
}
return nil
}
// Configure accepts a port number and configures
// the beacon, returning an address
func (b *Beacon) Configure(port int) (string, error) {
cmd := C.CString("CONFIGURE")
defer C.free(unsafe.Pointer(cmd))
cPort := C.CString(strconv.Itoa(port))
defer C.free(unsafe.Pointer(cPort))
rc := C.zstr_sendm(unsafe.Pointer(b.zactorT), cmd)
if rc == -1 {
return "", ErrActorCmd
}
rc = C.zstr_send(unsafe.Pointer(b.zactorT), cPort)
if rc == -1 {
return "", ErrActorCmd
}
cHostname := C.zstr_recv(unsafe.Pointer(b.zactorT))
hostname := C.GoString(cHostname)
return hostname, nil
}
// Publish publishes an announcement string at an interval
func (b *Beacon) Publish(announcement string, interval int) error {
cmd := C.CString("PUBLISH")
defer C.free(unsafe.Pointer(cmd))
cAnnouncement := C.CString(announcement)
defer C.free(unsafe.Pointer(cAnnouncement))
cInterval := C.CString(strconv.Itoa(interval))
defer C.free(unsafe.Pointer(cInterval))
rc := C.zstr_sendm(unsafe.Pointer(b.zactorT), cmd)
if rc == -1 {
return ErrActorCmd
}
rc = C.zstr_sendm(unsafe.Pointer(b.zactorT), cAnnouncement)
if rc == -1 {
return ErrActorCmd
}
rc = C.zstr_send(unsafe.Pointer(b.zactorT), cInterval)
if rc == -1 {
return ErrActorCmd
}
return nil
}
// PublishBytes publishes an announcement byte slice at an interval
func (b *Beacon) PublishBytes(announcement []byte, interval int) error {
rc := C.Beacon_publish(
unsafe.Pointer(b.zactorT),
unsafe.Pointer(&announcement[0]),
C.int(len(announcement)),
C.int(interval),
)
if rc == -1 {
return ErrActorCmd
}
return nil
}
// Subscribe subscribes to beacons matching the filter
func (b *Beacon) Subscribe(filter string) error {
cmd := C.CString("SUBSCRIBE")
defer C.free(unsafe.Pointer(cmd))
cFilter := C.CString(filter)
defer C.free(unsafe.Pointer(cFilter))
rc := C.zstr_sendm(unsafe.Pointer(b.zactorT), cmd)
if rc == -1 {
return ErrActorCmd
}
rc = C.zstr_send(unsafe.Pointer(b.zactorT), cFilter)
if rc == -1 {
return ErrActorCmd
}
return nil
}
// Recv waits for the specific timeout in milliseconds to receive a beacon
func (b *Beacon) Recv(timeout int) [][]byte {
C.zsock_set_rcvtimeo(unsafe.Pointer(b.zactorT), C.int(timeout))
cAddrFrame := C.zframe_recv(unsafe.Pointer(b.zactorT))
defer C.zframe_destroy(&cAddrFrame)
if cAddrFrame == nil {
return nil
}
addr := C.GoBytes(unsafe.Pointer(C.zframe_data(cAddrFrame)), C.int(C.zframe_size(cAddrFrame)))
cBeaconFrame := C.zframe_recv(unsafe.Pointer(b.zactorT))
defer C.zframe_destroy(&cBeaconFrame)
if cBeaconFrame == nil {
return nil
}
beacon := C.GoBytes(unsafe.Pointer(C.zframe_data(cBeaconFrame)), C.int(C.zframe_size(cBeaconFrame)))
return [][]byte{addr, beacon}
}
// Destroy destroys the beacon.
func (b *Beacon) Destroy() {
C.zactor_destroy(&b.zactorT)
}

158
vendor/gopkg.in/zeromq/goczmq.v4/cert.go generated vendored Normal file
View File

@ -0,0 +1,158 @@
package goczmq
/*
#include "czmq.h"
void Set_meta(zcert_t *self, const char *key, const char *value) {zcert_set_meta(self, key, "%s", value);}
*/
import "C"
import (
"fmt"
"os"
"unsafe"
)
// Cert wraps the CZMQ zcert class. It provides tools for
// creating and working with ZMQ CURVE security certs.
// The certs can be used as a temporary object in memory
// or persisted to disk. Certs are made up of a public
// and secret keypair + metadata.
type Cert struct {
zcertT *C.struct__zcert_t
}
// NewCert creates a new empty Cert instance
func NewCert() *Cert {
return &Cert{
zcertT: C.zcert_new(),
}
}
// NewCertFromKeys creates a new Cert from a public and private key
func NewCertFromKeys(public []byte, secret []byte) (*Cert, error) {
if len(public) != 32 {
return nil, fmt.Errorf("invalid public key")
}
if len(secret) != 32 {
return nil, fmt.Errorf("invalid private key")
}
return &Cert{
zcertT: C.zcert_new_from(
(*C.byte)(unsafe.Pointer(&public[0])),
(*C.byte)(unsafe.Pointer(&secret[0]))),
}, nil
}
// NewCertFromFile Load loads a Cert from files
func NewCertFromFile(filename string) (*Cert, error) {
_, err := os.Stat(filename)
if os.IsNotExist(err) {
return nil, ErrCertNotFound
}
cFilename := C.CString(filename)
defer C.free(unsafe.Pointer(cFilename))
cert := C.zcert_load(cFilename)
return &Cert{
zcertT: cert,
}, nil
}
// SetMeta sets meta data for a Cert
func (c *Cert) SetMeta(key string, value string) {
cKey := C.CString(key)
defer C.free(unsafe.Pointer(cKey))
cValue := C.CString(value)
defer C.free(unsafe.Pointer(cValue))
C.Set_meta(c.zcertT, cKey, cValue)
}
// Meta returns a meta data item from a Cert given a key
func (c *Cert) Meta(key string) string {
cKey := C.CString(key)
defer C.free(unsafe.Pointer(cKey))
val := C.zcert_meta(c.zcertT, cKey)
return C.GoString(val)
}
// PublicText returns the public key as a string
func (c *Cert) PublicText() string {
val := C.zcert_public_txt(c.zcertT)
return C.GoString(val)
}
// Apply sets the public and private keys for a socket
func (c *Cert) Apply(s *Sock) {
handle := C.zsock_resolve(unsafe.Pointer(s.zsockT))
C.zsock_set_curve_secretkey_bin(handle, C.zcert_secret_key(c.zcertT))
C.zsock_set_curve_publickey_bin(handle, C.zcert_public_key(c.zcertT))
}
// Dup duplicates a Cert
func (c *Cert) Dup() *Cert {
return &Cert{
zcertT: C.zcert_dup(c.zcertT),
}
}
// Equal checks two Certs for equality
func (c *Cert) Equal(compare *Cert) bool {
check := C.zcert_eq(c.zcertT, compare.zcertT)
if check == C.bool(true) {
return true
}
return false
}
// Print prints a Cert to stdout
func (c *Cert) Print() {
C.zcert_print(c.zcertT)
}
// SavePublic saves the public key to a file
func (c *Cert) SavePublic(filename string) error {
cFilename := C.CString(filename)
defer C.free(unsafe.Pointer(cFilename))
rc := C.zcert_save_public(c.zcertT, cFilename)
if rc == C.int(-1) {
return fmt.Errorf("SavePublic error")
}
return nil
}
// SaveSecret saves the secret key to a file
func (c *Cert) SaveSecret(filename string) error {
cFilename := C.CString(filename)
defer C.free(unsafe.Pointer(cFilename))
rc := C.zcert_save_secret(c.zcertT, cFilename)
if rc == C.int(-1) {
return fmt.Errorf("SaveSecret error")
}
return nil
}
// Save saves the public and secret key to filename and filename_secret
func (c *Cert) Save(filename string) error {
cFilename := C.CString(filename)
defer C.free(unsafe.Pointer(cFilename))
rc := C.zcert_save(c.zcertT, cFilename)
if rc == C.int(-1) {
return fmt.Errorf("SavePublic: error")
}
return nil
}
// Destroy destroys Cert instance
func (c *Cert) Destroy() {
C.zcert_destroy(&c.zcertT)
}

60
vendor/gopkg.in/zeromq/goczmq.v4/certstore.go generated vendored Normal file
View File

@ -0,0 +1,60 @@
package goczmq
/*
#include "czmq.h"
*/
import "C"
import
// CertStore works with directories of CURVE security certificates.
// It lets you easily load stores from disk and check if a key
// is present or not. This could be done fairly easily in pure
// Go, but is included for the sake of compatibility.
"unsafe"
type CertStore struct {
zcertstoreT *C.struct__zcertstore_t
}
// NewCertStore creates a new certificate store from
// a disk directory, loading and indexing all certificates.
func NewCertStore(location string) *CertStore {
cLocation := C.CString(location)
defer C.free(unsafe.Pointer(cLocation))
return &CertStore{
zcertstoreT: C.zcertstore_new(cLocation),
}
}
// Insert inserts a certificate into the store in memory.
// Call Save directly on the cert if you wish to save it
// to disk.
func (c *CertStore) Insert(cert *Cert) {
C.zcertstore_insert(c.zcertstoreT, &cert.zcertT)
}
// Lookup looks up a certificate in the store by public key and
// returns it.
func (c *CertStore) Lookup(key string) *Cert {
cKey := C.CString(key)
defer C.free(unsafe.Pointer(cKey))
ptr := C.zcertstore_lookup(c.zcertstoreT, cKey)
if ptr == nil {
return nil
}
return &Cert{
zcertT: ptr,
}
}
// Print prints a list of certificates in the store to stdout
func (c *CertStore) Print() {
C.zcertstore_print(c.zcertstoreT)
}
// Destroy destroys Cert instance
func (c *CertStore) Destroy() {
C.zcertstore_destroy(&c.zcertstoreT)
}

309
vendor/gopkg.in/zeromq/goczmq.v4/channeler.go generated vendored Normal file
View File

@ -0,0 +1,309 @@
package goczmq
/*
#include "czmq.h"
void Sock_init() {zsys_init();}
*/
import "C"
import (
"fmt"
"math/rand"
"strings"
)
// Channeler serializes all access to a socket through a send
// and receive channel. It starts two threads, on is used for receiving
// from the zeromq socket. The other is used to listen to the receive
// channel, and send everything back to the socket thrad for sending
// using an additional inproc socket.
type Channeler struct {
id int64
sockType int
endpoints string
subscribe *string
commandAddr string
proxyAddr string
commandChan chan<- string
SendChan chan<- [][]byte
RecvChan <-chan [][]byte
}
// Destroy sends a message to the Channeler to shut it down
// and clean it up.
func (c *Channeler) Destroy() {
c.commandChan <- "destroy"
}
// Subscribe to a Topic
func (c *Channeler) Subscribe(topic string) {
c.commandChan <- fmt.Sprintf("subscribe %s", topic)
}
// Unsubscribe from a Topic
func (c *Channeler) Unsubscribe(topic string) {
c.commandChan <- fmt.Sprintf("unsubscribe %s", topic)
}
// actor is a routine that handles communication with
// the zeromq socket.
func (c *Channeler) actor(recvChan chan<- [][]byte) {
pipe, err := NewPair(fmt.Sprintf(">%s", c.commandAddr))
if err != nil {
panic(err)
}
defer pipe.Destroy()
defer close(recvChan)
pull, err := NewPull(c.proxyAddr)
if err != nil {
panic(err)
}
defer pull.Destroy()
sock := NewSock(c.sockType)
defer sock.Destroy()
switch c.sockType {
case Pub, Rep, Pull, Router, XPub:
err = sock.Attach(c.endpoints, true)
if err != nil {
panic(err)
}
case Req, Push, Dealer, Pair, Stream, XSub:
err = sock.Attach(c.endpoints, false)
if err != nil {
panic(err)
}
case Sub:
if c.subscribe != nil {
subscriptions := strings.Split(*c.subscribe, ",")
for _, topic := range subscriptions {
sock.SetSubscribe(topic)
}
}
err = sock.Attach(c.endpoints, false)
if err != nil {
panic(err)
}
default:
panic(ErrInvalidSockType)
}
poller, err := NewPoller(sock, pull, pipe)
if err != nil {
panic(err)
}
defer poller.Destroy()
for {
s := poller.Wait(-1)
switch s {
case pipe:
cmd, err := pipe.RecvMessage()
if err != nil {
panic(err)
}
switch string(cmd[0]) {
case "destroy":
disconnect := strings.Split(c.endpoints, ",")
for _, endpoint := range disconnect {
sock.Disconnect(endpoint)
}
pipe.SendMessage([][]byte{[]byte("ok")})
goto ExitActor
case "subscribe":
topic := string(cmd[1])
sock.SetSubscribe(topic)
pipe.SendMessage([][]byte{[]byte("ok")})
case "unsubscribe":
topic := string(cmd[1])
sock.SetUnsubscribe(topic)
pipe.SendMessage([][]byte{[]byte("ok")})
}
case sock:
msg, err := s.RecvMessage()
if err != nil {
panic(err)
}
recvChan <- msg
case pull:
msg, err := pull.RecvMessage()
if err != nil {
panic(err)
}
err = sock.SendMessage(msg)
if err != nil {
panic(err)
}
}
}
ExitActor:
}
// channeler is a routine that handles the channel select loop
// and sends commands to the zeromq socket.
func (c *Channeler) channeler(commandChan <-chan string, sendChan <-chan [][]byte) {
push, err := NewPush(c.proxyAddr)
if err != nil {
panic(err)
}
defer push.Destroy()
pipe, err := NewPair(fmt.Sprintf("@%s", c.commandAddr))
if err != nil {
panic(err)
}
defer pipe.Destroy()
for {
select {
case cmd := <-commandChan:
switch cmd {
case "destroy":
err = pipe.SendFrame([]byte("destroy"), FlagNone)
if err != nil {
panic(err)
}
_, err = pipe.RecvMessage()
if err != nil {
panic(err)
}
goto ExitChanneler
default:
parts := strings.Split(cmd, " ")
numParts := len(parts)
message := make([][]byte, numParts, numParts)
for i, p := range parts {
message[i] = []byte(p)
}
err := pipe.SendMessage(message)
if err != nil {
panic(err)
}
_, err = pipe.RecvMessage()
if err != nil {
panic(err)
}
}
case msg := <-sendChan:
err := push.SendMessage(msg)
if err != nil {
panic(err)
}
}
}
ExitChanneler:
}
// newChanneler accepts arguments from the socket type based
// constructors and creates a new Channeler instance
func newChanneler(sockType int, endpoints string, subscribe ...string) *Channeler {
commandChan := make(chan string)
sendChan := make(chan [][]byte)
recvChan := make(chan [][]byte)
C.Sock_init()
c := &Channeler{
id: rand.Int63(),
endpoints: endpoints,
sockType: sockType,
commandChan: commandChan,
SendChan: sendChan,
RecvChan: recvChan,
}
c.commandAddr = fmt.Sprintf("inproc://actorcontrol%d", c.id)
c.proxyAddr = fmt.Sprintf("inproc://proxy%d", c.id)
if len(subscribe) > 0 {
topics := strings.Join(subscribe, ",")
c.subscribe = &topics
}
go c.channeler(commandChan, sendChan)
go c.actor(recvChan)
return c
}
// NewPubChanneler creats a new Channeler wrapping
// a Pub socket. The socket will bind by default.
func NewPubChanneler(endpoints string) *Channeler {
return newChanneler(Pub, endpoints, "")
}
// NewSubChanneler creates a new Channeler wrapping
// a Sub socket. Along with an endpoint list
// it accepts a comma delimited list of topics.
// The socket will connect by default.
func NewSubChanneler(endpoints string, subscribe ...string) *Channeler {
return newChanneler(Sub, endpoints, subscribe...)
}
// NewRepChanneler creates a new Channeler wrapping
// a Rep socket. The socket will bind by default.
func NewRepChanneler(endpoints string) *Channeler {
return newChanneler(Rep, endpoints, "")
}
// NewReqChanneler creates a new Channeler wrapping
// a Req socket. The socket will connect by default.
func NewReqChanneler(endpoints string) *Channeler {
return newChanneler(Req, endpoints, "")
}
// NewPullChanneler creates a new Channeler wrapping
// a Pull socket. The socket will bind by default.
func NewPullChanneler(endpoints string) *Channeler {
return newChanneler(Pull, endpoints, "")
}
// NewPushChanneler creates a new Channeler wrapping
// a Push socket. The socket will connect by default.
func NewPushChanneler(endpoints string) *Channeler {
return newChanneler(Push, endpoints, "")
}
// NewRouterChanneler creates a new Channeler wrapping
// a Router socket. The socket will Bind by default.
func NewRouterChanneler(endpoints string) *Channeler {
return newChanneler(Router, endpoints, "")
}
// NewDealerChanneler creates a new Channeler wrapping
// a Dealer socket. The socket will connect by default.
func NewDealerChanneler(endpoints string) *Channeler {
return newChanneler(Dealer, endpoints, "")
}
// NewXPubChanneler creates a new Channeler wrapping
// an XPub socket. The socket will Bind by default.
func NewXPubChanneler(endpoints string) *Channeler {
return newChanneler(XPub, endpoints, "")
}
// NewXSubChanneler creates a new Channeler wrapping
// a XSub socket. The socket will connect by default.
func NewXSubChanneler(endpoints string) *Channeler {
return newChanneler(XSub, endpoints, "")
}
// NewPairChanneler creates a new Channeler wrapping
// a Pair socket. The socket will connect by default.
func NewPairChanneler(endpoints string) *Channeler {
return newChanneler(Pair, endpoints, "")
}
// NewStreamChanneler creates a new Channeler wrapping
// a Pair socket. The socket will connect by default.
func NewStreamChanneler(endpoints string) *Channeler {
return newChanneler(Stream, endpoints, "")
}

201
vendor/gopkg.in/zeromq/goczmq.v4/goczmq.go generated vendored Normal file
View File

@ -0,0 +1,201 @@
// Package goczmq is a golang binding for CZMQ 3. CZMQ is a high level binding
// for ZeroMQ. Along with ZeroMQ socket support, CZMQ provides "actor" based
// services for authentication, service discovery, and creating proxies.
// GoCZMQ provides direct bindings to CZMQ along with higher level go
// abstractions such as channels and io.ReadWriter interface support.
//
// "Tell them I was a writer.
// A maker of software.
// A humanist. A father.
// And many things.
// But above all, a writer.
// Thank You. :)
// - Pieter Hintjens
package goczmq
/*
#cgo !windows pkg-config: libczmq libzmq libsodium
#cgo windows LDFLAGS: -lws2_32 -liphlpapi -lrpcrt4 -lsodium -lzmq -lczmq
#cgo windows CFLAGS: -Wno-pedantic-ms-format -DLIBCZMQ_EXPORTS -DZMQ_DEFINED_STDINT -DLIBCZMQ_EXPORTS -DZMQ_BUILD_DRAFT_API
#include "czmq.h"
#include <stdlib.h>
#include <string.h>
*/
import "C"
import (
"errors"
)
const (
// Req is a ZMQ_REQ socket type
Req = int(C.ZMQ_REQ)
// Rep is a ZMQ_REP socket type
Rep = int(C.ZMQ_REP)
// Dealer is a ZMQ_DEALER socket type
Dealer = int(C.ZMQ_DEALER)
// Router is a ZMQ_ROUTER socket type
Router = int(C.ZMQ_ROUTER)
// Pub is a ZMQ_PUB socket type
Pub = int(C.ZMQ_PUB)
// Sub is a ZMQ_SUB socket type
Sub = int(C.ZMQ_SUB)
// XPub is a ZMQ_XPUB socket type
XPub = int(C.ZMQ_XPUB)
// XSub is a ZMQ_XSUB socket type
XSub = int(C.ZMQ_XSUB)
// Push is a ZMQ_PUSH socket type
Push = int(C.ZMQ_PUSH)
// Pull is a ZMQ_PULL socket type
Pull = int(C.ZMQ_PULL)
// Pair is a ZMQ_PAIR socket type
Pair = int(C.ZMQ_PAIR)
// Stream is a ZMQ_STREAM socket type
Stream = int(C.ZMQ_STREAM)
// Pollin is the ZMQ_POLLIN constant
Pollin = int(C.ZMQ_POLLIN)
// Pollout is the ZMQ_POLLOUT constant
Pollout = int(C.ZMQ_POLLOUT)
// FlagMore is the ZFRAME_MORE flag
FlagMore = int(C.ZFRAME_MORE)
// FlagReuse is the ZFRAME_REUSE flag
FlagReuse = int(C.ZFRAME_REUSE)
//FlagDontWait is the ZFRAME_DONTWAIT flag
FlagDontWait = int(C.ZFRAME_DONTWAIT)
//FlagNone means there are no flags
FlagNone = 0
// CurveAllowAny is a semantic convenience for allowing
// any Curve clients
CurveAllowAny = "*"
//ZMQVersionMajor is the major version of the underlying ZeroMQ library
ZMQVersionMajor = int(C.ZMQ_VERSION_MAJOR)
//ZMQVersionMinor is the minor version of the underlying ZeroMQ library
ZMQVersionMinor = int(C.ZMQ_VERSION_MINOR)
//CZMQVersionMajor is the major version of the underlying CZMQ library
CZMQVersionMajor = int(C.CZMQ_VERSION_MAJOR)
// CZMQVersionMinor is the minor version of the underlying CZMQ library
CZMQVersionMinor = int(C.CZMQ_VERSION_MINOR)
)
var (
// ErrActorCmd is returned when there is an error sending
// a command to an actor
ErrActorCmd = errors.New("error sending actor command")
// ErrSockAttach is returned when an attach call to a socket fails
ErrSockAttach = errors.New("error attaching zsock")
// ErrInvalidSockType is returned when a function is called
// against a socket type that is not applicable for that socket type
ErrInvalidSockType = errors.New("invalid socket type")
// ErrSliceFull is returned if a []byte passed to Read was not
// large enough to hold the contents of a message
ErrSliceFull = errors.New("slice full")
// ErrConnect is returned if Connect on a socket fails
ErrConnect = errors.New("connect error")
// ErrDisconnect is returned if Disconnect on a socket fails
ErrDisconnect = errors.New("disconnect error")
// ErrBind is returned if Bind on a socket fails
ErrBind = errors.New("bind error")
// ErrUnbind is returned if Unbind on a socket fails
ErrUnbind = errors.New("unbind error")
// ErrSendFrame is returned if SendFrame on a socket fails
ErrSendFrame = errors.New("send frame error")
// ErrRecvFrame is returned if RecvFrame on a socket fails
ErrRecvFrame = errors.New("recv frame error")
// ErrRecvFrameAfterDestroy is returned if RecvFrame is called
// on a socket after it has been destroyed.
ErrRecvFrameAfterDestroy = errors.New("RecvFrame() is invalid on socket after Detroy() has been called.")
// ErrRecvMessage is returned if RecvMessage on a socket fails
ErrRecvMessage = errors.New("recv message error")
// ErrWaitAfterDestroy is returned by a Poller if there is an error
// accessing the underlying socket pointer when Wait is called
ErrWaitAfterDestroy = errors.New("Wait() is invalid on Poller after Destroy() is called.")
// ErrMultiPartUnsupported is returned when a function that does
// not support multi-part messages encounters a multi-part message
ErrMultiPartUnsupported = errors.New("function does not support multi part messages")
// ErrTimeout is returned when a function that supports timeouts times out
ErrTimeout = errors.New("function timed out")
// ErrCertNotFound is returned when NewCertFromFile tries to
// load a file that does not exist.
ErrCertNotFound = errors.New("file not found")
)
// Shutdown shuts down the CZMQ zsys layer.
// The CZMQ zsys layer normally shuts down on process termination through the
// use of an atexit cleanup function. Calling this allows the zsys layer to be
// shutdown manually.
//
// This is beneficial when CZMQ will no longer be used but the process will not
// be terminating. Any potential resources allocated by the zsys layer can be
// freed as they will no longer be needed.
func Shutdown() {
C.zsys_shutdown()
}
func getStringType(k int) string {
switch k {
case Req:
return "REQ"
case Rep:
return "REP"
case Dealer:
return "DEALER"
case Router:
return "ROUTER"
case Pub:
return "PUB"
case Sub:
return "SUB"
case XPub:
return "XPUB"
case XSub:
return "XSUB"
case Push:
return "PUSH"
case Pull:
return "PULL"
case Pair:
return "PAIR"
case Stream:
return "STREAM"
default:
return ""
}
}

22
vendor/gopkg.in/zeromq/goczmq.v4/license.xml generated vendored Normal file
View File

@ -0,0 +1,22 @@
<license>
Copyright (C) 2014 the Authors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</license>

106
vendor/gopkg.in/zeromq/goczmq.v4/poller.go generated vendored Normal file
View File

@ -0,0 +1,106 @@
package goczmq
/*
#include "czmq.h"
zpoller_t *Poller_new(void *reader) {
zpoller_t *poller = zpoller_new(reader, NULL);
return poller;
}
*/
import "C"
import (
"fmt"
"unsafe"
)
// Poller provides a simple wrapper to ZeroMQ's zmq_poll API,
// for the common case of reading from a number of sockets.
// Sockets can be added and removed from the running poller.
type Poller struct {
zpollerT *C.struct__zpoller_t
socks []*Sock
}
// NewPoller creates a new Poller instance.
// It accepts one or more readers to poll.
func NewPoller(readers ...*Sock) (*Poller, error) {
var p *Poller
if len(readers) == 0 {
p = &Poller{
zpollerT: C.Poller_new(nil),
socks: make([]*Sock, 0),
}
} else {
p = &Poller{
zpollerT: C.Poller_new(unsafe.Pointer(readers[0].zsockT)),
socks: make([]*Sock, 0),
}
p.socks = append(p.socks, readers[0])
if len(readers) == 1 {
return p, nil
}
for _, reader := range readers[1:] {
err := p.Add(reader)
if err != nil {
return nil, err
}
}
}
return p, nil
}
// Add adds a reader to be polled.
func (p *Poller) Add(reader *Sock) error {
rc := C.zpoller_add(p.zpollerT, unsafe.Pointer(reader.zsockT))
if int(rc) == -1 {
return fmt.Errorf("error adding reader")
}
p.socks = append(p.socks, reader)
return nil
}
// Remove removes a Sock from the poller
func (p *Poller) Remove(reader *Sock) {
numItems := len(p.socks)
for i := 0; i < numItems; i++ {
if p.socks[i] == reader {
if i == numItems-1 {
p.socks = p.socks[:i]
} else {
p.socks = append(p.socks[:i], p.socks[i+1:]...)
}
}
}
}
// Wait waits for the timeout period in milliseconds for a Pollin
// event, and returns the first socket that returns one
func (p *Poller) Wait(millis int) *Sock {
if p.zpollerT == nil {
// Null pointer. Something is wrong or we've already had `Destroy` invoked on us.
panic(ErrWaitAfterDestroy)
}
s := C.zpoller_wait(p.zpollerT, C.int(millis))
s = unsafe.Pointer(s)
if s == nil {
return nil
}
for _, sock := range p.socks {
if unsafe.Pointer(sock.zsockT) == s {
return sock
}
}
panic(fmt.Sprintf(
"Could not match received pointer with %v with any socket (%v)",
s, p.socks))
}
// Destroy destroys the Poller
func (p *Poller) Destroy() {
C.zpoller_destroy(&p.zpollerT)
}

171
vendor/gopkg.in/zeromq/goczmq.v4/proxy.go generated vendored Normal file
View File

@ -0,0 +1,171 @@
package goczmq
/*
#include "czmq.h"
zactor_t *Zproxy_new () {
zactor_t *proxy = zactor_new(zproxy, NULL);
return proxy;
}
*/
import "C"
import (
"unsafe"
)
// Proxy wraps the CZMQ zproxy actor. A proxy actor switches
// messages between a frontend and backend socket, and also
// provides an optional capture socket messages can be
// mirrored to. The proxy can be paused and resumed.
type Proxy struct {
zactorT *C.struct__zactor_t
}
// NewProxy creates a new Proxy instance.
func NewProxy() *Proxy {
p := &Proxy{}
p.zactorT = C.Zproxy_new()
return p
}
// SetFrontend accepts a socket type and endpoint, and sends a message
// to the zactor thread telling it to set up a socket bound to the endpoint.
func (p *Proxy) SetFrontend(sockType int, endpoint string) error {
typeString := getStringType(sockType)
cmd := C.CString("FRONTEND")
defer C.free(unsafe.Pointer(cmd))
cTypeString := C.CString(typeString)
defer C.free(unsafe.Pointer(cTypeString))
cEndpoint := C.CString(endpoint)
defer C.free(unsafe.Pointer(cEndpoint))
rc := C.zstr_sendm(unsafe.Pointer(p.zactorT), cmd)
if rc == -1 {
return ErrActorCmd
}
rc = C.zstr_sendm(unsafe.Pointer(p.zactorT), cTypeString)
if rc == -1 {
return ErrActorCmd
}
rc = C.zstr_send(unsafe.Pointer(p.zactorT), cEndpoint)
if rc == -1 {
return ErrActorCmd
}
rc = C.zsock_wait(unsafe.Pointer(p.zactorT))
if rc == -1 {
return ErrActorCmd
}
return nil
}
// SetBackend accepts a socket type and endpoint, and sends a message
// to the zactor thread telling it to set up a socket bound to the endpoint.
func (p *Proxy) SetBackend(sockType int, endpoint string) error {
typeString := getStringType(sockType)
cmd := C.CString("BACKEND")
defer C.free(unsafe.Pointer(cmd))
cTypeString := C.CString(typeString)
defer C.free(unsafe.Pointer(cTypeString))
cEndpoint := C.CString(endpoint)
defer C.free(unsafe.Pointer(cEndpoint))
rc := C.zstr_sendm(unsafe.Pointer(p.zactorT), cmd)
if rc == -1 {
return ErrActorCmd
}
rc = C.zstr_sendm(unsafe.Pointer(p.zactorT), cTypeString)
if rc == -1 {
return ErrActorCmd
}
rc = C.zstr_send(unsafe.Pointer(p.zactorT), cEndpoint)
if rc == -1 {
return ErrActorCmd
}
rc = C.zsock_wait(unsafe.Pointer(p.zactorT))
if rc == -1 {
return ErrActorCmd
}
return nil
}
// SetCapture accepts a socket endpoint and sets up a Push socket bound
// to that endpoint, that sends a copy of all messages passing through
// the proxy.
func (p *Proxy) SetCapture(endpoint string) error {
cmd := C.CString("CAPTURE")
defer C.free(unsafe.Pointer(cmd))
cEndpoint := C.CString(endpoint)
defer C.free(unsafe.Pointer(cEndpoint))
rc := C.zstr_sendm(unsafe.Pointer(p.zactorT), cmd)
if rc == -1 {
return ErrActorCmd
}
rc = C.zstr_send(unsafe.Pointer(p.zactorT), cEndpoint)
if rc == -1 {
return ErrActorCmd
}
return nil
}
// Pause sends a message to the zproxy actor telling it to pause.
func (p *Proxy) Pause() error {
cmd := C.CString("PAUSE")
defer C.free(unsafe.Pointer(cmd))
rc := C.zstr_send(unsafe.Pointer(p.zactorT), cmd)
if rc == -1 {
return ErrActorCmd
}
return nil
}
// Resume sends a message to the zproxy actor telling it to resume.
func (p *Proxy) Resume() error {
cmd := C.CString("RESUME")
defer C.free(unsafe.Pointer(cmd))
rc := C.zstr_send(unsafe.Pointer(p.zactorT), cmd)
if rc == -1 {
return ErrActorCmd
}
return nil
}
// Verbose sets the proxy to log information to stdout.
func (p *Proxy) Verbose() error {
cmd := C.CString("VERBOSE")
defer C.free(unsafe.Pointer(cmd))
rc := C.zstr_send(unsafe.Pointer(p.zactorT), cmd)
if rc == -1 {
return ErrActorCmd
}
return nil
}
// Destroy destroys the proxy.
func (p *Proxy) Destroy() {
C.zactor_destroy(&p.zactorT)
}

120
vendor/gopkg.in/zeromq/goczmq.v4/readwriter.go generated vendored Normal file
View File

@ -0,0 +1,120 @@
package goczmq
import (
"C"
"io"
)
// ReadWriter provides an io.ReadWriter compatible
// interface for goczmq.Sock
type ReadWriter struct {
sock *Sock
poller *Poller
clientIDs []string
frame []byte
currentIndex int
timeoutMillis int
}
// NewReadWriter accepts a sock and returns a goczmq.ReadWriter. The
// io.ReadWriter should now be considered responsible for this
// Sock.
func NewReadWriter(sock *Sock) (*ReadWriter, error) {
rw := &ReadWriter{
sock: sock,
timeoutMillis: -1,
}
var err error
rw.poller, err = NewPoller(rw.sock)
return rw, err
}
// SetTimeout sets the timeout on Read in millisecond. If no new
// data is received within the timeout period, Read will return
// an ErrTimeout
func (r *ReadWriter) SetTimeout(ms int) {
r.timeoutMillis = ms
}
// Read satisifies io.Read
func (r *ReadWriter) Read(p []byte) (int, error) {
var totalRead int
var totalFrame int
var flag int
var err error
if r.currentIndex == 0 {
s := r.poller.Wait(r.timeoutMillis)
if s == nil {
return totalRead, ErrTimeout
}
r.frame, flag, err = s.RecvFrame()
if s.GetType() == Router && r.currentIndex == 0 {
r.clientIDs = append(r.clientIDs, string(r.frame))
r.frame, flag, err = s.RecvFrame()
}
if flag == FlagMore {
return totalRead, ErrMultiPartUnsupported
}
if err != nil {
return totalRead, io.EOF
}
}
totalRead += copy(p[:], r.frame[r.currentIndex:])
totalFrame += len(r.frame)
if totalFrame-r.currentIndex > len(p) {
r.currentIndex = totalRead
} else {
r.currentIndex = 0
err = io.EOF
}
return totalRead, err
}
// Write satisfies io.Write
func (r *ReadWriter) Write(p []byte) (int, error) {
var total int
if r.sock.GetType() == Router {
err := r.sock.SendFrame(r.GetLastClientID(), FlagMore)
if err != nil {
return total, err
}
}
err := r.sock.SendFrame(p, 0)
if err != nil {
return total, err
}
return len(p), nil
}
// GetLastClientID returns the id of the last client you received
// a message from if the underlying socket is a Router socket
func (r *ReadWriter) GetLastClientID() []byte {
id := []byte(r.clientIDs[0])
r.clientIDs = r.clientIDs[1:]
return id
}
// SetLastClientID lets you manually set the id of the client
// you last received a message from if the underlying socket
// is a Router socket
func (r *ReadWriter) SetLastClientID(id []byte) {
r.clientIDs = append(r.clientIDs, string(id))
}
// Destroy destroys both the ReadWriter and the underlying Sock
func (r *ReadWriter) Destroy() {
r.sock.Destroy()
r.poller.Destroy()
}

435
vendor/gopkg.in/zeromq/goczmq.v4/sock.go generated vendored Normal file
View File

@ -0,0 +1,435 @@
package goczmq
/*
#include "czmq.h"
#include <stdlib.h>
#include <string.h>
int Sock_connect(zsock_t *self, const char *format) {return zsock_connect(self, format, NULL);}
int Sock_disconnect(zsock_t *self, const char *format) {return zsock_disconnect(self, format, NULL);}
int Sock_bind(zsock_t *self, const char *format) {return zsock_bind(self, format, NULL);}
int Sock_unbind(zsock_t *self, const char *format) {return zsock_unbind(self, format, NULL);}
int Sock_sendframe(zsock_t *sock, const void *data, size_t size, int flags) {
zframe_t *frame = zframe_new (data, size);
int rc = zframe_send (&frame, sock, flags);
return rc;
}
*/
import "C"
import (
"os"
"runtime"
"strings"
"unsafe"
)
// Sock wraps the CZMQ zsock class.
type Sock struct {
zsockT *C.struct__zsock_t
file string
line int
zType int
clientIDs []string
}
func init() {
if err := os.Setenv("ZSYS_SIGHANDLER", "false"); err != nil {
panic(err)
}
}
// GetLastClientID returns the id of the last client you received
// a message from if the underlying socket is a Router socket
// DEPRECATED: See goczmq.ReadWriter
func (s *Sock) GetLastClientID() []byte {
id := []byte(s.clientIDs[0])
s.clientIDs = s.clientIDs[1:]
return id
}
// SetLastClientID lets you manually set the id of the client
// you last received a message from if the underlying socket
// is a Router socket
// DEPRECATED: See goczmq.ReadWriter
func (s *Sock) SetLastClientID(id []byte) {
s.clientIDs = append(s.clientIDs, string(id))
}
// NewSock creates a new socket. The caller source and
// line number are passed so CZMQ can report socket leaks
// intelligently.
func NewSock(t int) *Sock {
var s *Sock
_, file, line, ok := runtime.Caller(1)
if ok {
s = &Sock{
file: file,
line: line,
zType: t,
clientIDs: make([]string, 0),
}
} else {
s = &Sock{
file: "",
line: 0,
zType: t,
clientIDs: make([]string, 0),
}
}
cFile := C.CString(s.file)
defer C.free(unsafe.Pointer(cFile))
s.zsockT = C.zsock_new_checked(C.int(s.zType), cFile, C.size_t(s.line))
return s
}
// Connect connects a socket to an endpoint
// returns an error if the connect failed.
func (s *Sock) Connect(endpoint string) error {
cEndpoint := C.CString(endpoint)
defer C.free(unsafe.Pointer(cEndpoint))
rc := C.Sock_connect(s.zsockT, cEndpoint)
if rc != C.int(0) {
return ErrConnect
}
return nil
}
// Disconnect disconnects a socket from an endpoint. If returns
// an error if the endpoint was not found
func (s *Sock) Disconnect(endpoint string) error {
cEndpoint := C.CString(endpoint)
defer C.free(unsafe.Pointer(cEndpoint))
rc := C.Sock_disconnect(s.zsockT, cEndpoint)
if int(rc) == -1 {
return ErrDisconnect
}
return nil
}
// Bind binds a socket to an endpoint. On success returns
// the port number used for tcp transports, or 0 for other
// transports. On failure returns a -1 for port, and an error.
func (s *Sock) Bind(endpoint string) (int, error) {
cEndpoint := C.CString(endpoint)
defer C.free(unsafe.Pointer(cEndpoint))
port := C.Sock_bind(s.zsockT, cEndpoint)
if port == C.int(-1) {
return -1, ErrBind
}
return int(port), nil
}
// Unbind unbinds a socket from an endpoint. If returns
// an error if the endpoint was not found
func (s *Sock) Unbind(endpoint string) error {
cEndpoint := C.CString(endpoint)
defer C.free(unsafe.Pointer(cEndpoint))
rc := C.Sock_unbind(s.zsockT, cEndpoint)
if int(rc) == -1 {
return ErrUnbind
}
return nil
}
// Attach attaches a socket to zero or more endpoints. If endpoints is not null,
// parses as list of ZeroMQ endpoints, separated by commas, and prefixed by
// '@' (to bind the socket) or '>' (to attach the socket). If the endpoint
// does not start with '@' or '>', the serverish argument determines whether
// it is used to bind (serverish = true) or connect (serverish = false)
func (s *Sock) Attach(endpoints string, serverish bool) error {
cEndpoints := C.CString(endpoints)
defer C.free(unsafe.Pointer(cEndpoints))
rc := C.zsock_attach(s.zsockT, cEndpoints, C._Bool(serverish))
if rc == -1 {
return ErrSockAttach
}
return nil
}
// NewPub creates a Pub socket and calls Attach.
// The socket will Bind by default.
func NewPub(endpoints string) (*Sock, error) {
s := NewSock(Pub)
return s, s.Attach(endpoints, true)
}
// NewSub creates a Sub socket and calls Attach.
// 'subscribe' is a comma delimited list of topics to subscribe to.
// The socket will Connect by default.
func NewSub(endpoints string, subscribe string) (*Sock, error) {
s := NewSock(Sub)
subscriptions := strings.Split(subscribe, ",")
for _, topic := range subscriptions {
s.SetSubscribe(topic)
}
return s, s.Attach(endpoints, false)
}
// NewRep creates a Rep socket and calls Attach.
// The socket will Bind by default.
func NewRep(endpoints string) (*Sock, error) {
s := NewSock(Rep)
return s, s.Attach(endpoints, true)
}
// NewReq creates a Req socket and calls Attach.
// The socket will Connect by default.
func NewReq(endpoints string) (*Sock, error) {
s := NewSock(Req)
return s, s.Attach(endpoints, false)
}
// NewPull creates a Pull socket and calls Attach.
// The socket will Bind by default.
func NewPull(endpoints string) (*Sock, error) {
s := NewSock(Pull)
return s, s.Attach(endpoints, true)
}
// NewPush creates a Push socket and calls Attach.
// The socket will Connect by default.
func NewPush(endpoints string) (*Sock, error) {
s := NewSock(Push)
return s, s.Attach(endpoints, false)
}
// NewRouter creates a Router socket and calls Attach.
// The socket will Bind by default.
func NewRouter(endpoints string) (*Sock, error) {
s := NewSock(Router)
return s, s.Attach(endpoints, true)
}
// NewDealer creates a Dealer socket and calls Attach.
// The socket will Connect by default.
func NewDealer(endpoints string) (*Sock, error) {
s := NewSock(Dealer)
return s, s.Attach(endpoints, false)
}
// NewXPub creates an XPub socket and calls Attach.
// The socket will Bind by default.
func NewXPub(endpoints string) (*Sock, error) {
s := NewSock(XPub)
return s, s.Attach(endpoints, true)
}
// NewXSub creates an XSub socket and calls Attach.
// The socket will Connect by default.
func NewXSub(endpoints string) (*Sock, error) {
s := NewSock(XSub)
return s, s.Attach(endpoints, false)
}
// NewPair creates a Pair socket and calls Attach.
// The socket will Connect by default.
func NewPair(endpoints string) (*Sock, error) {
s := NewSock(Pair)
return s, s.Attach(endpoints, false)
}
// NewStream creates a Stream socket and calls Attach.
// The socket will Connect by default.
func NewStream(endpoints string) (*Sock, error) {
s := NewSock(Stream)
return s, s.Attach(endpoints, false)
}
// Pollin returns true if there is a Pollin
// event on the socket
func (s *Sock) Pollin() bool {
return s.Events() == Pollin
}
// Pollout returns true if there is a Pollout
// event on the socket
func (s *Sock) Pollout() bool {
return s.Events() == Pollout
}
// SendFrame sends a byte array via the socket. For the flags
// value, use 0 for a single message, or SNDFlagMore if it is
// a multi-part message
func (s *Sock) SendFrame(data []byte, flags int) error {
var rc C.int
if len(data) == 0 {
rc = C.Sock_sendframe(s.zsockT, nil, C.size_t(0), C.int(flags))
} else {
rc = C.Sock_sendframe(s.zsockT, unsafe.Pointer(&data[0]), C.size_t(len(data)), C.int(flags))
}
if rc == C.int(-1) {
return ErrSendFrame
}
return nil
}
// RecvFrame reads a frame from the socket and returns it
// as a byte array, along with a more flag and and error
// (if there is an error)
func (s *Sock) RecvFrame() ([]byte, int, error) {
if s.zsockT == nil {
return nil, -1, ErrRecvFrameAfterDestroy
}
frame := C.zframe_recv(unsafe.Pointer(s.zsockT))
if frame == nil {
return []byte{0}, 0, ErrRecvFrame
}
dataSize := C.zframe_size(frame)
dataPtr := C.zframe_data(frame)
b := C.GoBytes(unsafe.Pointer(dataPtr), C.int(dataSize))
more := C.zframe_more(frame)
C.zframe_destroy(&frame)
return b, int(more), nil
}
// RecvFrameNoWait receives a frame from the socket
// and returns it as a byte array if one is waiting.
// Returns an empty frame, a 0 more flag and an error
// if one is not immediately available
func (s *Sock) RecvFrameNoWait() ([]byte, int, error) {
if !s.Pollin() {
return []byte{0}, 0, ErrRecvFrame
}
return s.RecvFrame()
}
// SendMessage accepts an array of byte arrays and
// sends it as a multi-part message.
func (s *Sock) SendMessage(parts [][]byte) error {
var f int
numParts := len(parts)
for i, val := range parts {
if i == numParts-1 {
f = 0
} else {
f = FlagMore
}
err := s.SendFrame(val, f)
if err != nil {
return err
}
}
return nil
}
// RecvMessage receives a full message from the socket
// and returns it as an array of byte arrays.
func (s *Sock) RecvMessage() ([][]byte, error) {
var msg [][]byte
for {
frame, flag, err := s.RecvFrame()
if err != nil {
return msg, err
}
msg = append(msg, frame)
if flag != FlagMore {
break
}
}
return msg, nil
}
// Read provides an io.Reader interface to a zeromq socket
// DEPRECATED: see goczmq.ReadWriter
func (s *Sock) Read(p []byte) (int, error) {
var totalRead int
var totalFrame int
frame, flag, err := s.RecvFrame()
if err != nil {
return totalRead, err
}
if s.GetType() == Router {
s.clientIDs = append(s.clientIDs, string(frame))
} else {
totalRead += copy(p[:], frame[:])
totalFrame += len(frame)
}
for flag == FlagMore {
frame, flag, err = s.RecvFrame()
if err != nil {
return totalRead, err
}
totalRead += copy(p[totalRead:], frame[:])
totalFrame += len(frame)
}
if totalFrame > len(p) {
err = ErrSliceFull
} else {
err = nil
}
return totalRead, err
}
// Write provides an io.Writer interface to a zeromq socket
// DEPRECATED: See goczmq.ReadWriter
func (s *Sock) Write(p []byte) (int, error) {
var total int
if s.GetType() == Router {
err := s.SendFrame(s.GetLastClientID(), FlagMore)
if err != nil {
return total, err
}
}
err := s.SendFrame(p, 0)
if err != nil {
return total, err
}
return len(p), nil
}
// RecvMessageNoWait receives a full message from the socket
// and returns it as an array of byte arrays if one is waiting.
// Returns an empty message and an error if one is not immediately
// available
func (s *Sock) RecvMessageNoWait() ([][]byte, error) {
var msg [][]byte
if !s.Pollin() {
return msg, ErrRecvMessage
}
for {
frame, flag, err := s.RecvFrame()
if err != nil {
return msg, err
}
msg = append(msg, frame)
if flag != FlagMore {
break
}
}
return msg, nil
}
// GetType returns the socket's type
func (s *Sock) GetType() int {
return s.zType
}
// Destroy destroys the underlying zsockT.
func (s *Sock) Destroy() {
cFile := C.CString(s.file)
defer C.free(unsafe.Pointer(cFile))
C.zsock_destroy_checked(&s.zsockT, cFile, C.size_t(s.line))
}

30
vendor/gopkg.in/zeromq/goczmq.v4/sock_draft.go generated vendored Normal file
View File

@ -0,0 +1,30 @@
// +build draft
package goczmq
/*
#include "czmq.h"
*/
import "C"
const (
// Scatter is a ZMQ_SCATTER socket type
Scatter = int(C.ZMQ_SCATTER)
// Gather is a ZMQ_GATHER socket type
Gather = int(C.ZMQ_GATHER)
)
// NewGather creates a Gather socket and calls Attach.
// The socket will Bind by default.
func NewGather(endpoints string) (*Sock, error) {
s := NewSock(Gather)
return s, s.Attach(endpoints, true)
}
// NewScatter creates a Scatter socket and calls Attach.
// The socket will Connect by default.
func NewScatter(endpoints string) (*Sock, error) {
s := NewSock(Scatter)
return s, s.Attach(endpoints, false)
}

765
vendor/gopkg.in/zeromq/goczmq.v4/sock_option.go generated vendored Normal file
View File

@ -0,0 +1,765 @@
//go:generate gsl sockopts.xml
package goczmq
/* =========================================================================
zsock_option - get/set 0MQ socket options
****************************************************
* GENERATED SOURCE CODE, DO NOT EDIT!! *
* TO CHANGE THIS, EDIT sockopts.gsl *
* AND RUN gsl -q sockopts.xml *
****************************************************
Copyright (c) the Contributors as noted in the AUTHORS file.
This file is part of goczmq, the high-level go binding for CZMQ:
http://github.com/zeromq/goczmq
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
=========================================================================
*/
/*
#include "czmq.h"
#include <stdlib.h>
#include <string.h>
*/
import "C"
import (
"unsafe"
)
// SetHeartbeatIvl sets the heartbeat_ivl option for the socket
func (s *Sock) SetHeartbeatIvl(val int) {
C.zsock_set_heartbeat_ivl(unsafe.Pointer(s.zsockT), C.int(val))
}
// HeartbeatIvl returns the current value of the socket's heartbeat_ivl option
func (s *Sock) HeartbeatIvl() int {
val := C.zsock_heartbeat_ivl(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetHeartbeatTtl sets the heartbeat_ttl option for the socket
func (s *Sock) SetHeartbeatTtl(val int) {
C.zsock_set_heartbeat_ttl(unsafe.Pointer(s.zsockT), C.int(val))
}
// HeartbeatTtl returns the current value of the socket's heartbeat_ttl option
func (s *Sock) HeartbeatTtl() int {
val := C.zsock_heartbeat_ttl(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetHeartbeatTimeout sets the heartbeat_timeout option for the socket
func (s *Sock) SetHeartbeatTimeout(val int) {
C.zsock_set_heartbeat_timeout(unsafe.Pointer(s.zsockT), C.int(val))
}
// HeartbeatTimeout returns the current value of the socket's heartbeat_timeout option
func (s *Sock) HeartbeatTimeout() int {
val := C.zsock_heartbeat_timeout(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetUseFd sets the use_fd option for the socket
func (s *Sock) SetUseFd(val int) {
C.zsock_set_use_fd(unsafe.Pointer(s.zsockT), C.int(val))
}
// UseFd returns the current value of the socket's use_fd option
func (s *Sock) UseFd() int {
val := C.zsock_use_fd(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetXPubManual sets the xpub_manual option for the socket
func (s *Sock) SetXPubManual(val int) {
C.zsock_set_xpub_manual(unsafe.Pointer(s.zsockT), C.int(val))
}
// SetXPubWelcomeMsg sets the xpub_welcome_msg option for the socket
func (s *Sock) SetXPubWelcomeMsg(val string) {
cVal := C.CString(val)
defer C.free(unsafe.Pointer(cVal))
C.zsock_set_xpub_welcome_msg(unsafe.Pointer(s.zsockT), cVal)
}
// SetStreamNotify sets the stream_notify option for the socket
func (s *Sock) SetStreamNotify(val int) {
C.zsock_set_stream_notify(unsafe.Pointer(s.zsockT), C.int(val))
}
// SetInvertMatching sets the invert_matching option for the socket
func (s *Sock) SetInvertMatching(val int) {
C.zsock_set_invert_matching(unsafe.Pointer(s.zsockT), C.int(val))
}
// InvertMatching returns the current value of the socket's invert_matching option
func (s *Sock) InvertMatching() int {
val := C.zsock_invert_matching(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetXPubVerboser sets the xpub_verboser option for the socket
func (s *Sock) SetXPubVerboser(val int) {
C.zsock_set_xpub_verboser(unsafe.Pointer(s.zsockT), C.int(val))
}
// SetConnectTimeout sets the connect_timeout option for the socket
func (s *Sock) SetConnectTimeout(val int) {
C.zsock_set_connect_timeout(unsafe.Pointer(s.zsockT), C.int(val))
}
// ConnectTimeout returns the current value of the socket's connect_timeout option
func (s *Sock) ConnectTimeout() int {
val := C.zsock_connect_timeout(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetTcpMaxrt sets the tcp_maxrt option for the socket
func (s *Sock) SetTcpMaxrt(val int) {
C.zsock_set_tcp_maxrt(unsafe.Pointer(s.zsockT), C.int(val))
}
// TcpMaxrt returns the current value of the socket's tcp_maxrt option
func (s *Sock) TcpMaxrt() int {
val := C.zsock_tcp_maxrt(unsafe.Pointer(s.zsockT))
return int(val)
}
// ThreadSafe returns the current value of the socket's thread_safe option
func (s *Sock) ThreadSafe() int {
val := C.zsock_thread_safe(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetMulticastMaxtpdu sets the multicast_maxtpdu option for the socket
func (s *Sock) SetMulticastMaxtpdu(val int) {
C.zsock_set_multicast_maxtpdu(unsafe.Pointer(s.zsockT), C.int(val))
}
// MulticastMaxtpdu returns the current value of the socket's multicast_maxtpdu option
func (s *Sock) MulticastMaxtpdu() int {
val := C.zsock_multicast_maxtpdu(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetVmciBufferSize sets the vmci_buffer_size option for the socket
func (s *Sock) SetVmciBufferSize(val int) {
C.zsock_set_vmci_buffer_size(unsafe.Pointer(s.zsockT), C.int(val))
}
// VmciBufferSize returns the current value of the socket's vmci_buffer_size option
func (s *Sock) VmciBufferSize() int {
val := C.zsock_vmci_buffer_size(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetVmciBufferMinSize sets the vmci_buffer_min_size option for the socket
func (s *Sock) SetVmciBufferMinSize(val int) {
C.zsock_set_vmci_buffer_min_size(unsafe.Pointer(s.zsockT), C.int(val))
}
// VmciBufferMinSize returns the current value of the socket's vmci_buffer_min_size option
func (s *Sock) VmciBufferMinSize() int {
val := C.zsock_vmci_buffer_min_size(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetVmciBufferMaxSize sets the vmci_buffer_max_size option for the socket
func (s *Sock) SetVmciBufferMaxSize(val int) {
C.zsock_set_vmci_buffer_max_size(unsafe.Pointer(s.zsockT), C.int(val))
}
// VmciBufferMaxSize returns the current value of the socket's vmci_buffer_max_size option
func (s *Sock) VmciBufferMaxSize() int {
val := C.zsock_vmci_buffer_max_size(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetVmciConnectTimeout sets the vmci_connect_timeout option for the socket
func (s *Sock) SetVmciConnectTimeout(val int) {
C.zsock_set_vmci_connect_timeout(unsafe.Pointer(s.zsockT), C.int(val))
}
// VmciConnectTimeout returns the current value of the socket's vmci_connect_timeout option
func (s *Sock) VmciConnectTimeout() int {
val := C.zsock_vmci_connect_timeout(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetTos sets the tos option for the socket
func (s *Sock) SetTos(val int) {
C.zsock_set_tos(unsafe.Pointer(s.zsockT), C.int(val))
}
// Tos returns the current value of the socket's tos option
func (s *Sock) Tos() int {
val := C.zsock_tos(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetRouterHandover sets the router_handover option for the socket
func (s *Sock) SetRouterHandover(val int) {
C.zsock_set_router_handover(unsafe.Pointer(s.zsockT), C.int(val))
}
// SetConnectRid sets the connect_rid option for the socket
func (s *Sock) SetConnectRid(val string) {
cVal := C.CString(val)
defer C.free(unsafe.Pointer(cVal))
C.zsock_set_connect_rid(unsafe.Pointer(s.zsockT), cVal)
}
// SetHandshakeIvl sets the handshake_ivl option for the socket
func (s *Sock) SetHandshakeIvl(val int) {
C.zsock_set_handshake_ivl(unsafe.Pointer(s.zsockT), C.int(val))
}
// HandshakeIvl returns the current value of the socket's handshake_ivl option
func (s *Sock) HandshakeIvl() int {
val := C.zsock_handshake_ivl(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetSocksProxy sets the socks_proxy option for the socket
func (s *Sock) SetSocksProxy(val string) {
cVal := C.CString(val)
defer C.free(unsafe.Pointer(cVal))
C.zsock_set_socks_proxy(unsafe.Pointer(s.zsockT), cVal)
}
// SocksProxy returns the current value of the socket's socks_proxy option
func (s *Sock) SocksProxy() string {
val := C.zsock_socks_proxy(unsafe.Pointer(s.zsockT))
return C.GoString(val)
}
// SetXPubNodrop sets the xpub_nodrop option for the socket
func (s *Sock) SetXPubNodrop(val int) {
C.zsock_set_xpub_nodrop(unsafe.Pointer(s.zsockT), C.int(val))
}
// SetRouterMandatory sets the router_mandatory option for the socket
func (s *Sock) SetRouterMandatory(val int) {
C.zsock_set_router_mandatory(unsafe.Pointer(s.zsockT), C.int(val))
}
// SetProbeRouter sets the probe_router option for the socket
func (s *Sock) SetProbeRouter(val int) {
C.zsock_set_probe_router(unsafe.Pointer(s.zsockT), C.int(val))
}
// SetReqRelaxed sets the req_relaxed option for the socket
func (s *Sock) SetReqRelaxed(val int) {
C.zsock_set_req_relaxed(unsafe.Pointer(s.zsockT), C.int(val))
}
// SetReqCorrelate sets the req_correlate option for the socket
func (s *Sock) SetReqCorrelate(val int) {
C.zsock_set_req_correlate(unsafe.Pointer(s.zsockT), C.int(val))
}
// SetConflate sets the conflate option for the socket
func (s *Sock) SetConflate(val int) {
C.zsock_set_conflate(unsafe.Pointer(s.zsockT), C.int(val))
}
// SetZapDomain sets the zap_domain option for the socket
func (s *Sock) SetZapDomain(val string) {
cVal := C.CString(val)
defer C.free(unsafe.Pointer(cVal))
C.zsock_set_zap_domain(unsafe.Pointer(s.zsockT), cVal)
}
// ZapDomain returns the current value of the socket's zap_domain option
func (s *Sock) ZapDomain() string {
val := C.zsock_zap_domain(unsafe.Pointer(s.zsockT))
return C.GoString(val)
}
// Mechanism returns the current value of the socket's mechanism option
func (s *Sock) Mechanism() int {
val := C.zsock_mechanism(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetPlainServer sets the plain_server option for the socket
func (s *Sock) SetPlainServer(val int) {
C.zsock_set_plain_server(unsafe.Pointer(s.zsockT), C.int(val))
}
// PlainServer returns the current value of the socket's plain_server option
func (s *Sock) PlainServer() int {
val := C.zsock_plain_server(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetPlainUsername sets the plain_username option for the socket
func (s *Sock) SetPlainUsername(val string) {
cVal := C.CString(val)
defer C.free(unsafe.Pointer(cVal))
C.zsock_set_plain_username(unsafe.Pointer(s.zsockT), cVal)
}
// PlainUsername returns the current value of the socket's plain_username option
func (s *Sock) PlainUsername() string {
val := C.zsock_plain_username(unsafe.Pointer(s.zsockT))
return C.GoString(val)
}
// SetPlainPassword sets the plain_password option for the socket
func (s *Sock) SetPlainPassword(val string) {
cVal := C.CString(val)
defer C.free(unsafe.Pointer(cVal))
C.zsock_set_plain_password(unsafe.Pointer(s.zsockT), cVal)
}
// PlainPassword returns the current value of the socket's plain_password option
func (s *Sock) PlainPassword() string {
val := C.zsock_plain_password(unsafe.Pointer(s.zsockT))
return C.GoString(val)
}
// SetCurveServer sets the curve_server option for the socket
func (s *Sock) SetCurveServer(val int) {
C.zsock_set_curve_server(unsafe.Pointer(s.zsockT), C.int(val))
}
// CurveServer returns the current value of the socket's curve_server option
func (s *Sock) CurveServer() int {
val := C.zsock_curve_server(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetCurvePublickey sets the curve_publickey option for the socket
func (s *Sock) SetCurvePublickey(val string) {
cVal := C.CString(val)
defer C.free(unsafe.Pointer(cVal))
C.zsock_set_curve_publickey(unsafe.Pointer(s.zsockT), cVal)
}
// CurvePublickey returns the current value of the socket's curve_publickey option
func (s *Sock) CurvePublickey() string {
val := C.zsock_curve_publickey(unsafe.Pointer(s.zsockT))
return C.GoString(val)
}
// SetCurveSecretkey sets the curve_secretkey option for the socket
func (s *Sock) SetCurveSecretkey(val string) {
cVal := C.CString(val)
defer C.free(unsafe.Pointer(cVal))
C.zsock_set_curve_secretkey(unsafe.Pointer(s.zsockT), cVal)
}
// CurveSecretkey returns the current value of the socket's curve_secretkey option
func (s *Sock) CurveSecretkey() string {
val := C.zsock_curve_secretkey(unsafe.Pointer(s.zsockT))
return C.GoString(val)
}
// SetCurveServerkey sets the curve_serverkey option for the socket
func (s *Sock) SetCurveServerkey(val string) {
cVal := C.CString(val)
defer C.free(unsafe.Pointer(cVal))
C.zsock_set_curve_serverkey(unsafe.Pointer(s.zsockT), cVal)
}
// CurveServerkey returns the current value of the socket's curve_serverkey option
func (s *Sock) CurveServerkey() string {
val := C.zsock_curve_serverkey(unsafe.Pointer(s.zsockT))
return C.GoString(val)
}
// SetGssapiServer sets the gssapi_server option for the socket
func (s *Sock) SetGssapiServer(val int) {
C.zsock_set_gssapi_server(unsafe.Pointer(s.zsockT), C.int(val))
}
// GssapiServer returns the current value of the socket's gssapi_server option
func (s *Sock) GssapiServer() int {
val := C.zsock_gssapi_server(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetGssapiPlaintext sets the gssapi_plaintext option for the socket
func (s *Sock) SetGssapiPlaintext(val int) {
C.zsock_set_gssapi_plaintext(unsafe.Pointer(s.zsockT), C.int(val))
}
// GssapiPlaintext returns the current value of the socket's gssapi_plaintext option
func (s *Sock) GssapiPlaintext() int {
val := C.zsock_gssapi_plaintext(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetGssapiPrincipal sets the gssapi_principal option for the socket
func (s *Sock) SetGssapiPrincipal(val string) {
cVal := C.CString(val)
defer C.free(unsafe.Pointer(cVal))
C.zsock_set_gssapi_principal(unsafe.Pointer(s.zsockT), cVal)
}
// GssapiPrincipal returns the current value of the socket's gssapi_principal option
func (s *Sock) GssapiPrincipal() string {
val := C.zsock_gssapi_principal(unsafe.Pointer(s.zsockT))
return C.GoString(val)
}
// SetGssapiServicePrincipal sets the gssapi_service_principal option for the socket
func (s *Sock) SetGssapiServicePrincipal(val string) {
cVal := C.CString(val)
defer C.free(unsafe.Pointer(cVal))
C.zsock_set_gssapi_service_principal(unsafe.Pointer(s.zsockT), cVal)
}
// GssapiServicePrincipal returns the current value of the socket's gssapi_service_principal option
func (s *Sock) GssapiServicePrincipal() string {
val := C.zsock_gssapi_service_principal(unsafe.Pointer(s.zsockT))
return C.GoString(val)
}
// SetIpv6 sets the ipv6 option for the socket
func (s *Sock) SetIpv6(val int) {
C.zsock_set_ipv6(unsafe.Pointer(s.zsockT), C.int(val))
}
// Ipv6 returns the current value of the socket's ipv6 option
func (s *Sock) Ipv6() int {
val := C.zsock_ipv6(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetImmediate sets the immediate option for the socket
func (s *Sock) SetImmediate(val int) {
C.zsock_set_immediate(unsafe.Pointer(s.zsockT), C.int(val))
}
// Immediate returns the current value of the socket's immediate option
func (s *Sock) Immediate() int {
val := C.zsock_immediate(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetRouterRaw sets the router_raw option for the socket
func (s *Sock) SetRouterRaw(val int) {
C.zsock_set_router_raw(unsafe.Pointer(s.zsockT), C.int(val))
}
// SetIpv4only sets the ipv4only option for the socket
func (s *Sock) SetIpv4only(val int) {
C.zsock_set_ipv4only(unsafe.Pointer(s.zsockT), C.int(val))
}
// Ipv4only returns the current value of the socket's ipv4only option
func (s *Sock) Ipv4only() int {
val := C.zsock_ipv4only(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetDelayAttachOnConnect sets the delay_attach_on_connect option for the socket
func (s *Sock) SetDelayAttachOnConnect(val int) {
C.zsock_set_delay_attach_on_connect(unsafe.Pointer(s.zsockT), C.int(val))
}
// Type returns the current value of the socket's type option
func (s *Sock) Type() int {
val := C.zsock_type(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetSndhwm sets the sndhwm option for the socket
func (s *Sock) SetSndhwm(val int) {
C.zsock_set_sndhwm(unsafe.Pointer(s.zsockT), C.int(val))
}
// Sndhwm returns the current value of the socket's sndhwm option
func (s *Sock) Sndhwm() int {
val := C.zsock_sndhwm(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetRcvhwm sets the rcvhwm option for the socket
func (s *Sock) SetRcvhwm(val int) {
C.zsock_set_rcvhwm(unsafe.Pointer(s.zsockT), C.int(val))
}
// Rcvhwm returns the current value of the socket's rcvhwm option
func (s *Sock) Rcvhwm() int {
val := C.zsock_rcvhwm(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetAffinity sets the affinity option for the socket
func (s *Sock) SetAffinity(val int) {
C.zsock_set_affinity(unsafe.Pointer(s.zsockT), C.int(val))
}
// Affinity returns the current value of the socket's affinity option
func (s *Sock) Affinity() int {
val := C.zsock_affinity(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetSubscribe sets the subscribe option for the socket
func (s *Sock) SetSubscribe(val string) {
cVal := C.CString(val)
defer C.free(unsafe.Pointer(cVal))
C.zsock_set_subscribe(unsafe.Pointer(s.zsockT), cVal)
}
// SetUnsubscribe sets the unsubscribe option for the socket
func (s *Sock) SetUnsubscribe(val string) {
cVal := C.CString(val)
defer C.free(unsafe.Pointer(cVal))
C.zsock_set_unsubscribe(unsafe.Pointer(s.zsockT), cVal)
}
// SetIdentity sets the identity option for the socket
func (s *Sock) SetIdentity(val string) {
cVal := C.CString(val)
defer C.free(unsafe.Pointer(cVal))
C.zsock_set_identity(unsafe.Pointer(s.zsockT), cVal)
}
// Identity returns the current value of the socket's identity option
func (s *Sock) Identity() string {
val := C.zsock_identity(unsafe.Pointer(s.zsockT))
return C.GoString(val)
}
// SetRate sets the rate option for the socket
func (s *Sock) SetRate(val int) {
C.zsock_set_rate(unsafe.Pointer(s.zsockT), C.int(val))
}
// Rate returns the current value of the socket's rate option
func (s *Sock) Rate() int {
val := C.zsock_rate(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetRecoveryIvl sets the recovery_ivl option for the socket
func (s *Sock) SetRecoveryIvl(val int) {
C.zsock_set_recovery_ivl(unsafe.Pointer(s.zsockT), C.int(val))
}
// RecoveryIvl returns the current value of the socket's recovery_ivl option
func (s *Sock) RecoveryIvl() int {
val := C.zsock_recovery_ivl(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetSndbuf sets the sndbuf option for the socket
func (s *Sock) SetSndbuf(val int) {
C.zsock_set_sndbuf(unsafe.Pointer(s.zsockT), C.int(val))
}
// Sndbuf returns the current value of the socket's sndbuf option
func (s *Sock) Sndbuf() int {
val := C.zsock_sndbuf(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetRcvbuf sets the rcvbuf option for the socket
func (s *Sock) SetRcvbuf(val int) {
C.zsock_set_rcvbuf(unsafe.Pointer(s.zsockT), C.int(val))
}
// Rcvbuf returns the current value of the socket's rcvbuf option
func (s *Sock) Rcvbuf() int {
val := C.zsock_rcvbuf(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetLinger sets the linger option for the socket
func (s *Sock) SetLinger(val int) {
C.zsock_set_linger(unsafe.Pointer(s.zsockT), C.int(val))
}
// Linger returns the current value of the socket's linger option
func (s *Sock) Linger() int {
val := C.zsock_linger(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetReconnectIvl sets the reconnect_ivl option for the socket
func (s *Sock) SetReconnectIvl(val int) {
C.zsock_set_reconnect_ivl(unsafe.Pointer(s.zsockT), C.int(val))
}
// ReconnectIvl returns the current value of the socket's reconnect_ivl option
func (s *Sock) ReconnectIvl() int {
val := C.zsock_reconnect_ivl(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetReconnectIvlMax sets the reconnect_ivl_max option for the socket
func (s *Sock) SetReconnectIvlMax(val int) {
C.zsock_set_reconnect_ivl_max(unsafe.Pointer(s.zsockT), C.int(val))
}
// ReconnectIvlMax returns the current value of the socket's reconnect_ivl_max option
func (s *Sock) ReconnectIvlMax() int {
val := C.zsock_reconnect_ivl_max(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetBacklog sets the backlog option for the socket
func (s *Sock) SetBacklog(val int) {
C.zsock_set_backlog(unsafe.Pointer(s.zsockT), C.int(val))
}
// Backlog returns the current value of the socket's backlog option
func (s *Sock) Backlog() int {
val := C.zsock_backlog(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetMaxmsgsize sets the maxmsgsize option for the socket
func (s *Sock) SetMaxmsgsize(val int) {
C.zsock_set_maxmsgsize(unsafe.Pointer(s.zsockT), C.int(val))
}
// Maxmsgsize returns the current value of the socket's maxmsgsize option
func (s *Sock) Maxmsgsize() int {
val := C.zsock_maxmsgsize(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetMulticastHops sets the multicast_hops option for the socket
func (s *Sock) SetMulticastHops(val int) {
C.zsock_set_multicast_hops(unsafe.Pointer(s.zsockT), C.int(val))
}
// MulticastHops returns the current value of the socket's multicast_hops option
func (s *Sock) MulticastHops() int {
val := C.zsock_multicast_hops(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetRcvtimeo sets the rcvtimeo option for the socket
func (s *Sock) SetRcvtimeo(val int) {
C.zsock_set_rcvtimeo(unsafe.Pointer(s.zsockT), C.int(val))
}
// Rcvtimeo returns the current value of the socket's rcvtimeo option
func (s *Sock) Rcvtimeo() int {
val := C.zsock_rcvtimeo(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetSndtimeo sets the sndtimeo option for the socket
func (s *Sock) SetSndtimeo(val int) {
C.zsock_set_sndtimeo(unsafe.Pointer(s.zsockT), C.int(val))
}
// Sndtimeo returns the current value of the socket's sndtimeo option
func (s *Sock) Sndtimeo() int {
val := C.zsock_sndtimeo(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetXPubVerbose sets the xpub_verbose option for the socket
func (s *Sock) SetXPubVerbose(val int) {
C.zsock_set_xpub_verbose(unsafe.Pointer(s.zsockT), C.int(val))
}
// SetTcpKeepalive sets the tcp_keepalive option for the socket
func (s *Sock) SetTcpKeepalive(val int) {
C.zsock_set_tcp_keepalive(unsafe.Pointer(s.zsockT), C.int(val))
}
// TcpKeepalive returns the current value of the socket's tcp_keepalive option
func (s *Sock) TcpKeepalive() int {
val := C.zsock_tcp_keepalive(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetTcpKeepaliveIdle sets the tcp_keepalive_idle option for the socket
func (s *Sock) SetTcpKeepaliveIdle(val int) {
C.zsock_set_tcp_keepalive_idle(unsafe.Pointer(s.zsockT), C.int(val))
}
// TcpKeepaliveIdle returns the current value of the socket's tcp_keepalive_idle option
func (s *Sock) TcpKeepaliveIdle() int {
val := C.zsock_tcp_keepalive_idle(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetTcpKeepaliveCnt sets the tcp_keepalive_cnt option for the socket
func (s *Sock) SetTcpKeepaliveCnt(val int) {
C.zsock_set_tcp_keepalive_cnt(unsafe.Pointer(s.zsockT), C.int(val))
}
// TcpKeepaliveCnt returns the current value of the socket's tcp_keepalive_cnt option
func (s *Sock) TcpKeepaliveCnt() int {
val := C.zsock_tcp_keepalive_cnt(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetTcpKeepaliveIntvl sets the tcp_keepalive_intvl option for the socket
func (s *Sock) SetTcpKeepaliveIntvl(val int) {
C.zsock_set_tcp_keepalive_intvl(unsafe.Pointer(s.zsockT), C.int(val))
}
// TcpKeepaliveIntvl returns the current value of the socket's tcp_keepalive_intvl option
func (s *Sock) TcpKeepaliveIntvl() int {
val := C.zsock_tcp_keepalive_intvl(unsafe.Pointer(s.zsockT))
return int(val)
}
// SetTcpAcceptFilter sets the tcp_accept_filter option for the socket
func (s *Sock) SetTcpAcceptFilter(val string) {
cVal := C.CString(val)
defer C.free(unsafe.Pointer(cVal))
C.zsock_set_tcp_accept_filter(unsafe.Pointer(s.zsockT), cVal)
}
// TcpAcceptFilter returns the current value of the socket's tcp_accept_filter option
func (s *Sock) TcpAcceptFilter() string {
val := C.zsock_tcp_accept_filter(unsafe.Pointer(s.zsockT))
return C.GoString(val)
}
// Rcvmore returns the current value of the socket's rcvmore option
func (s *Sock) Rcvmore() int {
val := C.zsock_rcvmore(unsafe.Pointer(s.zsockT))
return int(val)
}
// Fd returns the current value of the socket's fd option
func (s *Sock) Fd() int {
val := C.zsock_fd(unsafe.Pointer(s.zsockT))
return int(val)
}
// Events returns the current value of the socket's events option
func (s *Sock) Events() int {
val := C.zsock_events(unsafe.Pointer(s.zsockT))
return int(val)
}
// LastEndpoint returns the current value of the socket's last_endpoint option
func (s *Sock) LastEndpoint() string {
val := C.zsock_last_endpoint(unsafe.Pointer(s.zsockT))
return C.GoString(val)
}

84
vendor/gopkg.in/zeromq/goczmq.v4/sock_option.gsl generated vendored Normal file
View File

@ -0,0 +1,84 @@
.# This is a code generator built using the iMatix GSL code generation
.# language. See https://github.com/imatix/gsl for details. This script
.# is licensed under MIT/X11.
.#
.output "./sock_option.go"
//go:generate gsl sockopts.xml
package goczmq
/* =========================================================================
zsock_option - get/set 0MQ socket options
****************************************************
* GENERATED SOURCE CODE, DO NOT EDIT!! *
* TO CHANGE THIS, EDIT sockopts.gsl *
* AND RUN gsl -q sockopts.xml *
****************************************************
Copyright (c) the Contributors as noted in the AUTHORS file.
This file is part of goczmq, the high-level go binding for CZMQ:
http://github.com/zeromq/goczmq
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
=========================================================================
*/
/*
#include "czmq.h"
#include <stdlib.h>
#include <string.h>
*/
import "C"
import (
"unsafe"
)
.for version
.if major = "4"
.for option
.if mode = "rw" | mode = "w"
.if type = "uint64" | type = "int64" | type = "uint32" | type = "int"
// Set$(name:pascal) sets the $(name) option for the socket
func (s *Sock) Set$(name:pascal)(val $(gotype)) {
C.zsock_set_$(name)(unsafe.Pointer(s.zsockT), C.int(val))
}
.endif
.if type = "string" | type = "key"
// Set$(name:pascal) sets the $(name) option for the socket
func (s *Sock) Set$(name:pascal)(val $(gotype)) {
cVal := C.CString(val)
defer C.free(unsafe.Pointer(cVal))
C.zsock_set_$(name)(unsafe.Pointer(s.zsockT), cVal)
}
.endif
.endif
.if mode = "rw" | mode = "r"
.if type = "uint64" | type = "int64" | type = "uint32" | type = "int"
// $(name:pascal) returns the current value of the socket's $(name) option
func (s *Sock) $(name:pascal)() $(gotype) {
val := C.zsock_$(name)(unsafe.Pointer(s.zsockT))
return int(val)
}
.endif
.if type = "string" | type = "key"
// $(name:pascal) returns the current value of the socket's $(name) option
func (s *Sock) $(name:pascal)() $(gotype) {
val := C.zsock_$(name)(unsafe.Pointer(s.zsockT))
return C.GoString(val)
}
.endif
.endif
.endfor
.endif
.for source
$(string.trim(.):)
.endfor
.endfor

83
vendor/gopkg.in/zeromq/goczmq.v4/sock_option_test.gsl generated vendored Normal file
View File

@ -0,0 +1,83 @@
.# This is a code generator built using the iMatix GSL code generation
.# language. See https://github.com/imatix/gsl for details. This script
.# is licensed under MIT/X11.
.#
.output "./sock_option_test.go"
//go:generate gsl sockopts.xml
package goczmq
/* =========================================================================
zsock_option - get/set 0MQ socket options
****************************************************
* GENERATED SOURCE CODE, DO NOT EDIT!! *
****************************************************
Copyright (c) the Contributors as noted in the AUTHORS file.
This file is part of goczmq, the high-level go binding for CZMQ:
http://github.com/zeromq/goczmq
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
=========================================================================
*/
import (
"testing"
)
.for version
.if major = "4"
.for option where defined(test)
.if mode = "rw" | mode = "w"
.if type = "uint64" | type = "int64" | type = "uint32" | type = "int"
func Test$(name:pascal)(t *testing.T) {
sock := NewSock($(test:neat))
testval := $(test_value?'1':)
sock.Set$(name:pascal)(testval)
.if mode = "rw"
val := sock.$(name:pascal)()
if val != testval && val != 0 {
t.Errorf("$(name:pascal) returned %d, should be %d", val, testval)
}
.endif
sock.Destroy()
}
.endif
.if type = "string" | type = "key"
func Test$(name:pascal)(t *testing.T) {
sock := NewSock($(test:neat))
testval := "$(test_value?'test':)"
sock.Set$(name:pascal)(testval)
.if mode = "rw"
val := sock.$(name:pascal)()
if val != testval && val != "" {
t.Errorf("$(name:pascal) returned %s should be %s", val, testval)
}
.endif
sock.Destroy()
}
.endif
.if mode = "r"
.if type = "uint64" | type = "int64" | type = "uint32" | type = "int"
func Test$(name:pascal)(t *testing.T) {
sock := NewSock($(test:neat))
_ = sock.$(name:pascal)()
sock.Destroy()
}
.endif
.if type = "string" | type = "key"
func Test$(name:pascal)(t *testing.T) {
sock := NewSock($(test:pascal))
_ = sock.$(name:pascal)()
sock.Destroy()
}
.endif
.endif
.endif
.endfor
.endif
.endfor

32
vendor/gopkg.in/zeromq/goczmq.v4/sockopts.gsl generated vendored Normal file
View File

@ -0,0 +1,32 @@
.# This is a code generator built using the iMatix GSL code generation
.# language. See https://github.com/imatix/gsl for details. This script
.# is licensed under MIT/X11.
.#
.template 0
for version
# Expand any macros
for include
for options.macro where name = include.name
for . as child
copy child to version
endfor
endfor
endfor
# Preprocess options
for option
if type = "uint64" | type = "int64" | type = "uint32" | type = "int"
option.ctype = "int"
option.ctype_const = "int"
option.gotype = "int"
elsif type = "string" | type = "key"
option.ctype = "char *" # Enforce C strings
option.ctype_const = "const char *"
option.gotype = "string"
else
echo "E: unknown type: $(type)"
endif
endfor
endfor
.endtemplate
.include "sock_option.gsl"
.include "sock_option_test.gsl"

233
vendor/gopkg.in/zeromq/goczmq.v4/sockopts.xml generated vendored Normal file
View File

@ -0,0 +1,233 @@
<?xml?>
<!-- Used to generate the socket options interface
Requires gsl4 from https://github.com/imatix/gsl
use 'gsl sockopts'
-->
<options script = "sockopts">
<version major = "4" minor = "2" style = "macro">
<!-- Options that are new in 4.2 -->
<option name = "heartbeat_ivl" type = "int" mode = "rw" test = "DEALER"
test_value = "2000" />
<option name = "heartbeat_ttl" type = "int" mode = "rw" test = "DEALER"
test_value = "4000" />
<option name = "heartbeat_timeout" type = "int" mode = "rw" test = "DEALER"
test_value = "6000" />
<option name = "use_fd" type = "int" mode = "rw" test = "REQ"
test_value = "3" />
<option name = "xpub_manual" type = "int" mode = "w" test = "XPUB"
test_value = "1" >
<restrict type = "XPUB" />
</option>
<option name = "xpub_welcome_msg" type = "string" mode = "w" test = "XPUB"
test_value = "welcome" >
<restrict type = "XPUB" />
</option>
<option name = "stream_notify" type = "int" mode = "w" test = "STREAM"
test_value = "1" >
<restrict type = "STREAM" />
</option>
<option name = "invert_matching" type = "int" mode = "rw" test = "XPUB"
test_value = "1" >
<restrict type = "XPUB" />
<restrict type = "PUB" />
<restrict type = "SUB" />
</option>
<option name = "xpub_verboser" type = "int" mode = "w" test = "XPUB"
test_value = "1" >
<restrict type = "XPUB" />
</option>
<option name = "connect_timeout" type = "int" mode = "rw" test = "DEALER"
test_value = "200" />
<option name = "tcp_maxrt" type = "int" mode = "rw" test = "DEALER"
test_value = "200" />
<option name = "thread_safe" type = "int" mode = "r" test = "DEALER"
test_value = "0" />
<option name = "multicast_maxtpdu" type = "int" mode = "rw" test = "DEALER"
test_value = "1400" />
<!-- We don't test these as libzmq doesn't always support VMCI -->
<option name = "vmci_buffer_size" type = "uint64" mode = "rw" />
<option name = "vmci_buffer_min_size" type = "uint64" mode = "rw" />
<option name = "vmci_buffer_max_size" type = "uint64" mode = "rw" />
<option name = "vmci_connect_timeout" type = "int" mode = "rw" />
</version>
<version major = "4" minor = "1" style = "macro">
<!-- Options that are new in 4.1 -->
<option name = "tos" type = "int" mode = "rw" test = "DEALER" />
<option name = "router_handover" type = "int" mode = "w" test = "ROUTER">
<restrict type = "ROUTER" />
</option>
<option name = "connect_rid" type = "key" mode = "w" test = "ROUTER"
test_value = "ABCD" >
<restrict type = "ROUTER" />
<restrict type = "STREAM" />
</option>
<option name = "handshake_ivl" type = "int" mode = "rw" test = "DEALER"
test_value = "200" />
<option name = "socks_proxy" type = "string" mode = "rw" test = "DEALER"
test_value = "127.0.0.1" />
<option name = "xpub_nodrop" type = "int" mode = "w" test = "XPUB"
test_value = "1" >
<restrict type = "XPUB" />
<restrict type = "PUB" />
</option>
</version>
<version major = "4" style = "macro">
<!-- Options that are new in 4.1 -->
<option name = "tos" type = "int" mode = "rw" test = "Dealer" />
<option name = "router_handover" type = "int" mode = "w" test = "Router">
<restrict type = "Router" />
</option>
<!-- Options that are new in 4.0 -->
<option name = "router_mandatory" type = "int" mode = "w" test = "Router">
<restrict type = "Router" />
</option>
<option name = "probe_router" type = "int" mode = "w" test = "Dealer">
<restrict type = "Router" />
<restrict type = "Dealer" />
<restrict type = "Req" />
</option>
<option name = "req_relaxed" type = "int" mode = "w" test = "Req">
<restrict type = "Req" />
</option>
<option name = "req_correlate" type = "int" mode = "w" test = "Req">
<restrict type = "Req" />
</option>
<option name = "conflate" type = "int" mode = "w" test = "Push">
<restrict type = "Push" />
<restrict type = "Pull" />
<restrict type = "Pub" />
<restrict type = "Sub" />
<restrict type = "Dealer" />
</option>
<!-- Security options -->
<option name = "zap_domain" type = "string" mode = "rw" test = "Sub" />
<option name = "mechanism" type = "int" mode = "r" test = "Sub" />
<option name = "plain_server" type = "int" mode = "rw" test = "Pub" />
<option name = "plain_username" type = "string" mode = "rw" test = "Sub" />
<option name = "plain_password" type = "string" mode = "rw" test = "Sub" />
<!-- We don't test these as libzmq doesn't always support CURVE security -->
<option name = "curve_server" type = "int" mode = "rw" />
<option name = "curve_publickey" type = "key" mode = "rw" />
<option name = "curve_secretkey" type = "key" mode = "rw" />
<option name = "curve_serverkey" type = "key" mode = "rw" />
<!-- We don't test these as libzmq doesn't always support GSSAPI security -->
<option name = "gssapi_server" type = "int" mode = "rw" />
<option name = "gssapi_plaintext" type = "int" mode = "rw" />
<option name = "gssapi_principal" type = "string" mode = "rw" />
<option name = "gssapi_service_principal"
type = "string" mode = "rw" />
<!-- New names for deprecated 3.x options -->
<option name = "ipv6" type = "int" mode = "rw" test = "Sub" />
<option name = "immediate" type = "int" mode = "rw" test = "Dealer" />
<!-- Deprecated 3.x options -->
<option name = "router_raw" type = "int" mode = "w" test = "Router">
<restrict type = "Router" />
</option>
<option name = "ipv4only" type = "int" mode = "rw" test = "Sub" />
<option name = "delay_attach_on_connect"
type = "int" mode = "w" test = "Pub" />
<!-- Options that are the same in 3.x -->
<include name = "3-x options" />
</version>
<version major = "3" style = "macro">
<!-- Options that are carried forward to 4.0 -->
<include name = "3-x options" />
<!-- Options that are deprecated in 4.0 -->
<option name = "router_raw" type = "int" mode = "w" test = "Router">
<restrict type = "Router" />
</option>
<option name = "ipv4only" type = "int" mode = "rw" test = "Sub" />
<option name = "delay_attach_on_connect"
type = "int" mode = "w" test = "Pub" />
</version>
<!-- Legacy version 2 -->
<version major = "2" style = "macro">
<option name = "hwm" type = "uint64" mode = "rw" test = "Sub" />
<option name = "swap" type = "int64" mode = "rw" test = "Sub" />
<option name = "affinity" type = "uint64" mode = "rw" test = "Sub" />
<option name = "identity" type = "string" mode = "rw" test = "Sub" />
<option name = "rate" type = "int64" mode = "rw" test = "Sub" />
<option name = "recovery_ivl" type = "int64" mode = "rw" test = "Sub" />
<option name = "recovery_ivl_msec" type = "int64" mode = "rw" test = "Sub" />
<option name = "mcast_loop" type = "int64" mode = "rw" test = "Sub" />
<option name = "rcvtimeo" type = "int" mode = "rw" test = "Sub" minor = "2" />
<option name = "sndtimeo" type = "int" mode = "rw" test = "Sub" minor = "2" />
<option name = "sndbuf" type = "uint64" mode = "rw" test = "Sub" />
<option name = "rcvbuf" type = "uint64" mode = "rw" test = "Sub" />
<option name = "linger" type = "int" mode = "rw" test = "Sub" />
<option name = "reconnect_ivl" type = "int" mode = "rw" test = "Sub" />
<option name = "reconnect_ivl_max" type = "int" mode = "rw" test = "Sub" />
<option name = "backlog" type = "int" mode = "rw" test = "Sub" />
<option name = "subscribe" type = "string" mode = "w" test = "Sub">
<restrict type = "Sub" />
</option>
<option name = "unsubscribe" type = "string" mode = "w" test = "Sub">
<restrict type = "Sub" />
</option>
<option name = "type" type = "int" mode = "r" test = "Sub" />
<option name = "rcvmore" type = "int64" mode = "r" test = "Sub" />
<option name = "fd" type = "int" mode = "r" test = "Sub" />
<option name = "events" type = "uint32" mode = "r" test = "Sub" />
</version>
<macro name = "3-x options">
<option name = "type" type = "int" mode = "r" test = "Sub" />
<option name = "sndhwm" type = "int" mode = "rw" test = "Pub" />
<option name = "rcvhwm" type = "int" mode = "rw" test = "Sub" />
<option name = "affinity" type = "uint64" mode = "rw" test = "Sub" />
<option name = "subscribe" type = "string" mode = "w" test = "Sub">
<restrict type = "Sub" />
</option>
<option name = "unsubscribe" type = "string" mode = "w" test = "Sub">
<restrict type = "Sub" />
</option>
<option name = "identity" type = "string" mode = "rw" test = "Dealer">
<restrict type = "Req" />
<restrict type = "Rep" />
<restrict type = "Dealer" />
<restrict type = "Router" />
</option>
<option name = "rate" type = "int" mode = "rw" test = "Sub" />
<option name = "recovery_ivl" type = "int" mode = "rw" test = "Sub" />
<option name = "sndbuf" type = "int" mode = "rw" test = "Pub" />
<option name = "rcvbuf" type = "int" mode = "rw" test = "Sub" />
<option name = "linger" type = "int" mode = "rw" test = "Sub" />
<option name = "reconnect_ivl" type = "int" mode = "rw" test = "Sub" />
<option name = "reconnect_ivl_max" type = "int" mode = "rw" test = "Sub" />
<option name = "backlog" type = "int" mode = "rw" test = "Sub" />
<option name = "maxmsgsize" type = "int64" mode = "rw" test = "Sub" />
<option name = "multicast_hops" type = "int" mode = "rw" test = "Sub" />
<option name = "rcvtimeo" type = "int" mode = "rw" test = "Sub" />
<option name = "sndtimeo" type = "int" mode = "rw" test = "Sub" />
<option name = "xpub_verbose" type = "int" mode = "w" test = "XPub">
<restrict type = "XPub" />
</option>
<option name = "tcp_keepalive" type = "int" mode = "rw" test = "Sub" />
<option name = "tcp_keepalive_idle"
type = "int" mode = "rw" test = "Sub" />
<option name = "tcp_keepalive_cnt" type = "int" mode = "rw" test = "Sub" />
<option name = "tcp_keepalive_intvl"
type = "int" mode = "rw" test = "Sub" />
<option name = "tcp_accept_filter" type = "string" mode = "rw" test = "Sub"
test_value = "127.0.0.1" />
<option name = "rcvmore" type = "int" mode = "r" test = "Sub" />
<option name = "fd" type = "int" mode = "r" test = "Sub" />
<option name = "events" type = "int" mode = "r" test = "Sub" />
<option name = "last_endpoint" type = "string" mode = "r" test = "Sub" />
</macro>
</options>

10
vendor/modules.txt vendored Normal file
View File

@ -0,0 +1,10 @@
# golang.org/x/net v0.0.0-20210510120150-4163338589ed
## explicit
golang.org/x/net/internal/socks
golang.org/x/net/proxy
# gopkg.in/irc.v3 v3.1.4
## explicit
gopkg.in/irc.v3
# gopkg.in/zeromq/goczmq.v4 v4.1.0
## explicit
gopkg.in/zeromq/goczmq.v4