Example #1
0
package acmeendpoints

import (
	"bytes"
	"crypto/sha256"
	"crypto/x509"
	"errors"
	"fmt"
	"github.com/hlandau/acme/acmeapi"
	"github.com/hlandau/xlog"
	"golang.org/x/net/context"
	"net/url"
	"regexp"
)

var log, Log = xlog.New("acme.endpoints")

// Returned when no matching endpoint can be found.
var ErrNotFound = errors.New("no corresponding endpoint found")

// Finds an endpoint with the given directory URL. If no such endpoint is
// found, returns ErrNotFound.
func ByDirectoryURL(directoryURL string) (*Endpoint, error) {
	for _, e := range endpoints {
		if directoryURL == e.DirectoryURL {
			return e, nil
		}
	}

	return nil, ErrNotFound
}
Example #2
0
import "github.com/willf/bloom"

//import "github.com/hlandau/degoutils/dbutil"
import "text/template"
import htmltemplate "html/template"
import "time"

//import "github.com/hlandau/degoutils/sendemail"
import "crypto/sha256"

//import "github.com/jackc/pgx"

import "database/sql"
import "github.com/lib/pq"

var log, Log = xlog.New("ctmon.server")

type Config struct {
	DBURI string `default:"" usage:"PostgreSQL DB URI"`
}

type Server struct {
	cfg         Config
	stopping    int32
	stopWait    sync.WaitGroup
	stopChan    chan struct{}
	stopOnce    sync.Once
	bloomFilter *bloom.BloomFilter
	//dbpool             *pgx.ConnPool
	dbpool             *sql.DB
	textNotifyEmailTpl *template.Template
Example #3
0
// Package fdb allows for the use of a filesystem directory as a simple
// database on UNIX-like systems.
package fdb

import (
	"fmt"
	"github.com/hlandau/xlog"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
)

var log, Log = xlog.New("fdb")

// FDB instance.
type DB struct {
	cfg        Config
	path       string
	extantDirs map[string]struct{}
}

// FDB configuration.
type Config struct {
	Path        string
	Permissions []Permission
}

// Expresses the permission policy for a given path. The first match is used.
type Permission struct {
	// The path to which the permission applies. May contain wildcards and must
Example #4
0
File: main.go Project: hlandau/acme
	"github.com/hlandau/acme/hooks"
	"github.com/hlandau/acme/interaction"
	"github.com/hlandau/acme/redirector"
	"github.com/hlandau/acme/responder"
	"github.com/hlandau/acme/storage"
	"github.com/hlandau/acme/storageops"
	"github.com/hlandau/dexlogconfig"
	"github.com/hlandau/xlog"
	"gopkg.in/alecthomas/kingpin.v2"
	"gopkg.in/hlandau/easyconfig.v1/adaptflag"
	"gopkg.in/hlandau/service.v2"
	"gopkg.in/square/go-jose.v1"
	"gopkg.in/yaml.v2"
)

var log, Log = xlog.New("acmetool")

var (
	stateFlag = kingpin.Flag("state", "Path to the state directory (env: ACME_STATE_DIR)").
			Default(storage.RecommendedPath).
			Envar("ACME_STATE_DIR").
			PlaceHolder(storage.RecommendedPath).
			String()

	hooksFlag = kingpin.Flag("hooks", "Path to the notification hooks directory (env: ACME_HOOKS_DIR)").
			Default(hooks.RecommendedPath).
			Envar("ACME_HOOKS_DIR").
			PlaceHolder(hooks.RecommendedPath).
			String()

	batchFlag = kingpin.Flag("batch", "Do not attempt interaction; useful for cron jobs. (acmetool can still obtain responses from a response file, if one was provided.)").
Example #5
0
	"errors"
	"fmt"
	deos "github.com/hlandau/goutils/os"
	"github.com/hlandau/xlog"
	"gopkg.in/hlandau/svcutils.v1/chroot"
	"gopkg.in/hlandau/svcutils.v1/passwd"
	"gopkg.in/tylerb/graceful.v1"
	"html"
	"net"
	"net/http"
	"os"
	"sync/atomic"
	"time"
)

var log, Log = xlog.New("acme.redirector")

// Configuration for redirector.
type Config struct {
	Bind          string `default:":80" usage:"Bind address"`
	ChallengePath string `default:"" usage:"Path containing HTTP challenge files"`
	ChallengeGID  string `default:"" usage:"GID to chgrp the challenge path to (optional)"`
}

// Simple HTTP to HTTPS redirector.
type Redirector struct {
	cfg          Config
	httpServer   graceful.Server
	httpListener net.Listener
	stopping     uint32
}
Example #6
0
// Package tpl provides facilities for loading and displaying templates.
package tpl

import "path/filepath"
import "github.com/flosch/pongo2"
import "fmt"
import "github.com/hlandau/xlog"
import "net/http"
import "github.com/hlandau/degoutils/web/miscctx"
import "github.com/hlandau/degoutils/web/opts"
import "github.com/hlandau/degoutils/vfs"
import "github.com/hlandau/degoutils/binarc"
import "io"

var log, Log = xlog.New("web.tpl")

// Loaded templates.
var templates = map[string]*pongo2.Template{}

// Try to find a template with the given name. Returns nil if there is no such
// template loaded.
func GetTemplate(name string) *pongo2.Template {
	return templates[name]
}

// Load all templates from the given directory. The templates must have the file extension ".p2".
func LoadTemplates(dirname string) error {
	err := binarc.Setup(opts.BaseDir)
	if err != nil {
		return err
	}
Example #7
0
import (
	"crypto/sha256"
	"encoding/base64"
	"encoding/binary"
	"github.com/hlandau/degoutils/vfs"
	"github.com/hlandau/xlog"
	"github.com/rjeczalik/notify"
	"io"
	"os"
	"path/filepath"
	"regexp"
	"sync"
	"time"
)

var log, Log = xlog.New("web.assetmgr")

var allDigits = regexp.MustCompile(`^[0-9]+$`)

// Asset manager configuration.
type Config struct {
	Path string // Path to assets.
}

// Represents a known asset file.
type file struct {
	mtime    time.Time
	tag      string
	sha256   []byte
	fullpath string
}
Example #8
0
package dbutil

import (
	"fmt"
	"github.com/hlandau/xlog"
	"github.com/jackc/pgx"
	"strings"
)

var log, Log = xlog.New("dbutil")

type DBI interface {
	Exec(sql string, args ...interface{}) (pgx.CommandTag, error)
	Query(sql string, args ...interface{}) (*pgx.Rows, error)
	QueryRow(sql string, args ...interface{}) *pgx.Row
}

func makeInsertPairs(extras []string, args ...interface{}) (keystr, placeholderstr string, values []interface{}) {
	isKey := true
	var keys = make([]string, len(extras), len(args)/2+len(extras))
	var placeholders = make([]string, 0, len(args)/2+len(extras))
	values = make([]interface{}, len(extras), len(args)/2+len(extras))
	no := 1
	for i := 0; i < len(extras); i++ {
		keys[i] = extras[i]
		placeholders = append(placeholders, fmt.Sprintf("$%d", no))
		no++
	}
	for _, arg := range args {
		if isKey {
			keys = append(keys, "\""+arg.(string)+"\"")
Example #9
0
package binarc

import "sync"
import "os"
import "gopkg.in/hlandau/svcutils.v1/exepath"
import "github.com/hlandau/degoutils/vfs"
import "github.com/hlandau/degoutils/vfs/zipfs"
import "github.com/hlandau/xlog"

var log, Log = xlog.New("binarc")

var setupOnce sync.Once
var inlineArchive vfs.Filesystem

func Setup(path string) error {
	setupOnce.Do(func() {
		f, err := openSelfFile()
		if err != nil {
			log.Errore(err, "cannot open self")
			return
		}

		finfo, err := f.Stat()
		if err != nil {
			f.Close()
			log.Errore(err, "cannot stat self")
			return
		}

		arc, err := zipfs.New(f, finfo.Size())
		if err != nil {
Example #10
0
package responder

import (
	"crypto"
	"crypto/sha256"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"github.com/hlandau/acme/interaction"
	"github.com/hlandau/xlog"
	"github.com/square/go-jose"
)

// Log site.
var log, Log = xlog.New("acme.responder")

// A Responder implements a challenge type.
//
// After successfully instantiating a responder, you should call Start.
//
// You should then use the return values of Validation() and
// ValidationSigningKey() to submit the challenge response.
//
// Once the challenge has been completed, as determined by polling, you must
// call Stop. If RequestDetectedChan() is non-nil, it provides a hint as to
// when polling may be fruitful.
type Responder interface {
	// Become ready to be interrogated by the ACME server.
	Start(interactor interaction.Interactor) error
Example #11
0
package portmap

import "net"
import "time"
import "github.com/hlandau/portmap/ssdp"
import "github.com/hlandau/portmap/upnp"
import "github.com/hlandau/portmap/natpmp"
import "github.com/hlandau/xlog"

var log, Log = xlog.New("portmap")

type mode int

const (
	modeNATPMP mode = iota
	modeUPnP
)

func (m *mapping) portMappingLoop(gwa []net.IP) {
	aborting := false
	mode := modeNATPMP
	var ok bool
	var d time.Duration
	for {
		// Already inactive (e.g. expired or was never active), so no need to do anything.
		if aborting && !m.lIsActive() {
			return
		}

		switch mode {
		case modeNATPMP:
Example #12
0
// Package redissession provides a Redis-based session store.
package redissession

import (
	"bytes"
	"encoding/gob"
	"fmt"
	"github.com/garyburd/redigo/redis"
	"github.com/hlandau/degoutils/web/session/storage"
	"github.com/hlandau/xlog"
	"github.com/satori/go.uuid"
	"time"
)

var log, Log = xlog.New("web.session.redissession")

type sess struct {
	Data     map[string]interface{}
	LastSeen time.Time
}

// Redis-backed session store configuration.
type Config struct {
	// After what period of inactivity should sessions expire?
	//
	// Default: 4 hours.
	Expiry time.Duration

	// Required. Function returning a Redis connection (e.g. from a pool). Will
	// be closed when no longer needed.
	GetConn func() (redis.Conn, error)
Example #13
0
import "os"
import "os/exec"
import "net"
import "gopkg.in/hlandau/easymetric.v1/cexp"
import "gopkg.in/hlandau/easyconfig.v1/cflag"
import "path/filepath"
import "github.com/hlandau/xlog"
import "sync"
import "io"
import "gopkg.in/alexcesaro/quotedprintable.v3"
import "mime/multipart"
import "net/textproto"

var cEmailsSent = cexp.NewCounter("sendemail.emailsSent")

var log, Log = xlog.New("sendemail")

var (
	fg               = cflag.NewGroup(nil, "sendemail")
	smtpAddressFlag  = cflag.String(fg, "smtpaddress", "", "SMTP address (hostname[:port])")
	smtpUsernameFlag = cflag.String(fg, "smtpusername", "", "SMTP username")
	smtpPasswordFlag = cflag.String(fg, "smtppassword", "", "SMTP password")
	sendmailPathFlag = cflag.String(fg, "sendmailpath", "", "path to /usr/sbin/sendmail")
	numSendersFlag   = cflag.Int(fg, "numsenders", 2, "number of asynchronous e. mail senders")
	fromFlag         = cflag.String(fg, "from", "nobody@localhost", "Default from address")
)

var sendChan = make(chan *Email, 32)
var startOnce sync.Once

func sendLoop() {
Example #14
0
// Package opts provides miscellaneous configurable globals commonly required
// by web application servers.
package opts

import "gopkg.in/hlandau/easyconfig.v1/cflag"
import "github.com/hlandau/xlog"
import "crypto/rand"
import "crypto/hmac"
import "crypto/sha256"
import "encoding/hex"

var log, Log = xlog.New("web.opts")

// Development mode? In development mode, the application server may behave
// differently. Errors may be reported differently, assets may be reloaded
// automatically, etc.
//
// Configurable 'devmode'.
var DevMode bool

var devModeFlag = cflag.BoolVar(nil, &DevMode, "devmode", false, "Development mode?")

// Base directory. Some files may be looked for relative to this directory; templates, assets, etc.
//
// Configurable 'basedir'.
var BaseDir string

var baseDirFlag = cflag.StringVar(nil, &BaseDir, "basedir", "", "Base dir (containing assets, tpl directories, etc.)")

// Base URL. This is the canonical base URL, which will be used in e.g. e.
// mails. It should not have a trailing slash.
Example #15
0
package interaction

import (
	"fmt"
	"github.com/hlandau/xlog"
)

var log, Log = xlog.New("acme.interactor")

// Used by Auto. If this is set, only autoresponses can be used. Any challenge
// without an autoresponse fails. --batch.
var NonInteractive = false

type autoInteractor struct{}

// Interactor which automatically uses the most suitable challenge method.
var Auto Interactor = autoInteractor{}

// Used by Auto. If this is non-nil, all challenges are directed to it. There
// is no fallback if the interceptor fails. Autoresponses and NonInteractive
// take precedence over this.
var Interceptor Interactor

// Used by Auto. Do not use the Dialog mode. --stdio.
var NoDialog = false

func (autoInteractor) Prompt(c *Challenge) (*Response, error) {
	r, err := Responder.Prompt(c)
	if err == nil || c.Implicit {
		return r, err
	}
Example #16
0
// Package cspreport provides facilities for logging CSP and HPKP violation
// reports.
package cspreport

import "time"
import "net/http"
import "encoding/json"
import "github.com/hlandau/xlog"

// Logger which generates CSP and HPKP reports.
var log, Log = xlog.New("web.cspreport")

// HTTP handler which logs CSP and HPKP reports.
var Handler http.Handler

func init() {
	Handler = http.HandlerFunc(handler)
}

func handler(rw http.ResponseWriter, req *http.Request) {
	if req.Header.Get("Content-Type") != "application/csp-report" {
		pkpHandler(rw, req)
		return
	}

	r := CSPReport{}
	err := json.NewDecoder(req.Body).Decode(&r)
	if err != nil {
		rw.WriteHeader(400)
		return
	}
Example #17
0
// Package memorysession provides an in-memory session store. Can optionally be
// used with a fallback backend, in which case it acts as a sort of cache.
package memorysession

import "github.com/satori/go.uuid"
import "github.com/hlandau/degoutils/web/session/storage"
import "github.com/hlandau/xlog"
import "time"
import "sync"

var log, Log = xlog.New("web.session.memorysession")

type sess struct {
	data     map[string]interface{}
	lastSeen time.Time
}

// Memory-based session store configuration.
type Config struct {
	// After what period of inactivity should sessions be removed from the store?
	// Sessions will still be left in any fallback store which is configured.
	//
	// Defaults to 4 hours.
	Expiry time.Duration

	// If set, acts as a writeback cache. If a session is not found in memory, it
	// is looked for in the fallback store. All session writes are persisted to
	// the fallback store.
	FallbackStore storage.Store
}
Example #18
0
import "net/mail"
import "strings"
import "time"

// Provides an abstract zone file for the Namecoin .bit TLD.
type Backend struct {
	//s *Server
	nc         namecoin.Conn
	cache      lru.Cache // items are of type *Domain
	cacheMutex sync.Mutex
	cfg        Config
}

const defaultMaxEntries = 100

var log, Log = xlog.New("ncdns.backend")

// Backend configuration.
type Config struct {
	NamecoinConn namecoin.Conn

	// Username and password to use for connecting to the Namecoin JSON-RPC interface.
	//RPCUsername string
	//RPCPassword string

	// hostname:port to use for connecting to the Namecoin JSON-RPC interface.
	//RPCAddress string

	// Maximum entries to permit in name cache. If zero, a default value is used.
	CacheMaxEntries int
Example #19
0
	"html"
	"io"
	"mime/multipart"
	"net/http"
	"net/mail"
	"net/textproto"
	"net/url"
	"regexp"
	"strings"
	"time"
)

var authGroup = cflag.NewGroup(nil, "auth")
var registerCAPTCHAFlag = cflag.Bool(authGroup, "registercaptcha", false, "Require CAPTCHA on register?")

var log, Log = xlog.New("web.auth")

type Backend interface {
	GetDatabase() *pgx.ConnPool
	GetCAPTCHA() *captcha.Config
}

type GetBackendFunc func(req *http.Request) Backend

var GetBackend GetBackendFunc

func Auth_Login_GET(rw http.ResponseWriter, req *http.Request) {
	tpl.MustShow(req, "auth/login", nil)
}

func Auth_Login_POST(rw http.ResponseWriter, req *http.Request) {
Example #20
0
import "gopkg.in/hlandau/madns.v1"
import "github.com/hlandau/ncdns/backend"
import "github.com/hlandau/ncdns/namecoin"
import "github.com/miekg/dns"
import "os"
import "net"
import "fmt"
import "sync"
import "strings"
import "path/filepath"
import "crypto"
import "github.com/hlandau/xlog"

const version = "1.0"

var log, Log = xlog.New("ncdns.server")

type Server struct {
	cfg Config

	engine       madns.Engine
	namecoinConn namecoin.Conn

	mux         *dns.ServeMux
	udpListener *dns.Server
	tcpListener *dns.Server
	wgStart     sync.WaitGroup
}

type Config struct {
	Bind           string `default:":53" usage:"Address to bind to (e.g. 0.0.0.0:53)"`
Example #21
0
// Package solver figures out how to complete authorizations and completes them
// by instantiating responders.
package solver

import (
	"fmt"
	"github.com/hlandau/acme/acmeapi"
	"github.com/hlandau/acme/responder"
	denet "github.com/hlandau/degoutils/net"
	"github.com/hlandau/xlog"
	"golang.org/x/net/context"
	"time"
)

var log, Log = xlog.New("acme.solver")

// Returned if all combinations fail.
var ErrFailedAllCombinations = fmt.Errorf("failed all combinations")

type authState struct {
	c            *acmeapi.Client
	dnsName      string
	ccfg         responder.ChallengeConfig
	ctx          context.Context
	pref         TypePreferencer
	webPaths     []string
	listenAddrs  []string
	priorKeyFunc responder.PriorKeyFunc
}

// Attempts to authorize a hostname using the given client. webPaths and
Example #22
0
	"crypto/x509/pkix"
	"encoding/asn1"
	"fmt"
	"github.com/hlandau/acme/acmeapi"
	"github.com/hlandau/acme/acmeapi/acmeendpoints"
	"github.com/hlandau/acme/hooks"
	"github.com/hlandau/acme/responder"
	"github.com/hlandau/acme/solver"
	"github.com/hlandau/acme/storage"
	"github.com/hlandau/xlog"
	"github.com/jmhodges/clock"
	"golang.org/x/net/context"
	"sort"
)

var log, Log = xlog.New("acme.reconcilator")

// Internal use only. Used for testing purposes. Do not change.
var InternalClock = clock.Default()

type reconcile struct {
	store storage.Store
}

func EnsureRegistration(store storage.Store) error {
	r := reconcile{
		store: store,
	}

	return r.EnsureRegistration()
}
Example #23
0
package ctclient

import denet "github.com/hlandau/degoutils/net"
import "net/http"
import "sync"
import "time"
import "encoding/json"
import "fmt"
import "strings"
import "github.com/hlandau/xlog"
import "encoding/binary"

var log, Log = xlog.New("ctclient")

type EntryType uint16

const (
	X509Entry EntryType = iota
	PrecertEntry
)

func (et EntryType) String() string {
	switch et {
	case X509Entry:
		return "x509Entry"
	case PrecertEntry:
		return "precertEntry"
	default:
		return "unknown"
	}
}
Example #24
0
	"github.com/hlandau/degoutils/web/tpl"
	"github.com/hlandau/degoutils/web/weberror"
	"github.com/hlandau/xlog"
	"github.com/llgcode/draw2d"
	"gopkg.in/hlandau/easyconfig.v1/cflag"
	"gopkg.in/hlandau/easymetric.v1/cexp"
	"gopkg.in/tylerb/graceful.v1"
	"net"
	"net/http"
	"net/url"
	"path/filepath"
	"strings"
	"time"
)

var log, Log = xlog.New("web")

var cRequestsHandled = cexp.NewCounter("web.requestsHandled")

var bindFlag = cflag.String(nil, "bind", ":3400", "HTTP binding address")
var redisAddressFlag = cflag.String(nil, "redisaddress", "localhost:6379", "Redis address")
var redisPasswordFlag = cflag.String(nil, "redispassword", "", "Redis password")
var redisPrefixFlag = cflag.String(nil, "redisprefix", "", "Redis prefix")
var captchaFontPathFlag = cflag.String(nil, "captchafontpath", "", "Path to CAPTCHA font directory")
var reportURI = cflag.String(nil, "reporturi", "/.csp-report", "CSP/PKP report URI")

var Router *mux.Router

func init() {
	Router = mux.NewRouter()
	Router.KeepContext = true
Example #25
0
File: dht.go Project: hlandau/dht
// Package dht implements a BitTorrent Mainline DHT node.
//
// Implements BEP-0005 and BEP-0032.
package dht

import (
	denet "github.com/hlandau/degoutils/net"
	"github.com/hlandau/goutils/clock"
	"github.com/hlandau/xlog"
	"net"
	"sync"
	"sync/atomic"
	"time"
)

var log, Log = xlog.New("dht")

// DHT structure, setup and teardown. {{{1

type DHT struct {
	cfg      Config
	wantList []string

	// Requests from the client.
	addNodeChan               chan addNodeInfo
	requestPeersChan          chan requestPeersInfo
	requestReachableNodesChan chan chan<- []NodeInfo

	// Channels to return information to the client.
	peersChan chan PeerResult
Example #26
0
// Package notify provides a function to execute a directory of executable
// hooks, used when a certificate has been updated.
package notify

import (
	"fmt"
	"github.com/hlandau/xlog"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

// Log site.
var log, Log = xlog.New("acme.notify")

// The default hook path is the path at which executable hooks are looked for
// for notification purposes. On POSIX-like systems, this is usually
// "/usr/lib/acme/hooks" (or "/usr/libexec/acme/hooks" if /usr/libexec exists).
var DefaultHookPath string

func init() {
	// Allow overriding at build time.
	p := DefaultHookPath
	if p == "" {
		p = "/usr/lib/acme/hooks"
	}

	if _, err := os.Stat("/usr/libexec"); strings.HasPrefix(p, "/usr/lib/") && err == nil {
		p = "/usr/libexec" + p[8:]
	}
Example #27
0
	"fmt"
	"github.com/hlandau/acme/acmeapi"
	"github.com/hlandau/acme/acmeapi/acmeendpoints"
	"github.com/hlandau/acme/acmeapi/acmeutils"
	"github.com/hlandau/acme/hooks"
	"github.com/hlandau/acme/responder"
	"github.com/hlandau/acme/solver"
	"github.com/hlandau/acme/storage"
	"github.com/hlandau/xlog"
	"github.com/jmhodges/clock"
	"golang.org/x/net/context"
	"sort"
	"strings"
)

var log, Log = xlog.New("acme.storageops")

// Internal use only. Used for testing purposes. Do not change.
var InternalClock = clock.Default()

type reconcile struct {
	store storage.Store

	// Cache of account clients to avoid duplicated directory lookups.
	accountClients map[*storage.Account]*acmeapi.Client
}

func makeReconcile(store storage.Store) *reconcile {
	return &reconcile{
		store:          store,
		accountClients: map[*storage.Account]*acmeapi.Client{},
Example #28
0
// This package is now deprecated. Please use hlandau/xlog.
package log

import "github.com/hlandau/xlog"

var log, Log = xlog.New("legacy-log")

func Panic(v ...interface{}) {
	log.Panic(v...)
}

func Panice(err error, v ...interface{}) {
	log.Panice(err, v...)
}

func Fatal(v ...interface{}) {
	log.Fatal(v...)
}

func Fatale(err error, v ...interface{}) {
	log.Fatale(err, v...)
}

func Error(v ...interface{}) {
	log.Error(v...)
}

func Errore(err error, v ...interface{}) {
	log.Errore(err, v...)
}
Example #29
0
// Package hooks provides functions to invoke a directory of executable hooks,
// used to provide arbitrary handling of significant events.
package hooks

import (
	"fmt"
	"github.com/hlandau/xlog"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

// Log site.
var log, Log = xlog.New("acme.hooks")

// The default hook path is the path at which executable hooks are looked for
// for notification purposes. On POSIX-like systems, this is usually
// "/usr/lib/acme/hooks" (or "/usr/libexec/acme/hooks" if /usr/libexec exists).
var DefaultPath string

func init() {
	// Allow overriding at build time.
	p := DefaultPath
	if p == "" {
		p = "/usr/lib/acme/hooks"
	}

	if _, err := os.Stat("/usr/libexec"); strings.HasPrefix(p, "/usr/lib/") && err == nil {
		p = "/usr/libexec" + p[8:]
	}
Example #30
0
File: krpc.go Project: hlandau/dht
package krpc

import (
	"bytes"
	"crypto/rand"
	"encoding/binary"
	"fmt"
	denet "github.com/hlandau/degoutils/net"
	"github.com/hlandau/xlog"
	"github.com/hlandauf/bencode"
	"net"
	"reflect"
	"sync/atomic"
)

var log, Log = xlog.New("dht.krpc")

// KRPC message.
type Message struct {
	TxID string `bencode:"t"` // For correlation.
	Type string `bencode:"y"` // Query, response or error? [qre]

	Method string             `bencode:"q,omitempty"` // Queries: method name.
	Args   interface{}        `bencode:"-"`           // Queries: Query arguments.
	Args_  bencode.RawMessage `bencode:"a,omitempty"` // (Internal use only.)

	Response  interface{}        `bencode:"-"`           // Responses: Response value.
	Response_ bencode.RawMessage `bencode:"r,omitempty"` // (Internal use only.)

	Error []interface{} `bencode:"e,omitempty"` // Error responses: error information.