Split stamps into package
This commit is contained in:
parent
e49ce4f12b
commit
eb5f391fa6
|
@ -13,6 +13,7 @@ import (
|
||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
"github.com/jedisct1/dlog"
|
"github.com/jedisct1/dlog"
|
||||||
|
"github.com/jedisct1/dnscrypt-proxy/stamps"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
@ -380,11 +381,11 @@ func ConfigLoad(proxy *Proxy, svcFlag *string) error {
|
||||||
func (config *Config) printRegisteredServers(proxy *Proxy, jsonOutput bool) {
|
func (config *Config) printRegisteredServers(proxy *Proxy, jsonOutput bool) {
|
||||||
var summary []ServerSummary
|
var summary []ServerSummary
|
||||||
for _, registeredServer := range proxy.registeredServers {
|
for _, registeredServer := range proxy.registeredServers {
|
||||||
addrStr, port := registeredServer.stamp.serverAddrStr, DefaultPort
|
addrStr, port := registeredServer.stamp.ServerAddrStr, stamps.DefaultPort
|
||||||
port = ExtractPort(addrStr, port)
|
port = ExtractPort(addrStr, port)
|
||||||
addrs := make([]string, 0)
|
addrs := make([]string, 0)
|
||||||
if registeredServer.stamp.proto == StampProtoTypeDoH && len(registeredServer.stamp.providerName) > 0 {
|
if registeredServer.stamp.Proto == stamps.StampProtoTypeDoH && len(registeredServer.stamp.ProviderName) > 0 {
|
||||||
providerName := registeredServer.stamp.providerName
|
providerName := registeredServer.stamp.ProviderName
|
||||||
var host string
|
var host string
|
||||||
host, port = ExtractHostAndPort(providerName, port)
|
host, port = ExtractHostAndPort(providerName, port)
|
||||||
addrs = append(addrs, host)
|
addrs = append(addrs, host)
|
||||||
|
@ -394,13 +395,13 @@ func (config *Config) printRegisteredServers(proxy *Proxy, jsonOutput bool) {
|
||||||
}
|
}
|
||||||
serverSummary := ServerSummary{
|
serverSummary := ServerSummary{
|
||||||
Name: registeredServer.name,
|
Name: registeredServer.name,
|
||||||
Proto: registeredServer.stamp.proto.String(),
|
Proto: registeredServer.stamp.Proto.String(),
|
||||||
IPv6: strings.HasPrefix(addrStr, "["),
|
IPv6: strings.HasPrefix(addrStr, "["),
|
||||||
Ports: []int{port},
|
Ports: []int{port},
|
||||||
Addrs: addrs,
|
Addrs: addrs,
|
||||||
DNSSEC: registeredServer.stamp.props&ServerInformalPropertyDNSSEC != 0,
|
DNSSEC: registeredServer.stamp.Props&stamps.ServerInformalPropertyDNSSEC != 0,
|
||||||
NoLog: registeredServer.stamp.props&ServerInformalPropertyNoLog != 0,
|
NoLog: registeredServer.stamp.Props&stamps.ServerInformalPropertyNoLog != 0,
|
||||||
NoFilter: registeredServer.stamp.props&ServerInformalPropertyNoFilter != 0,
|
NoFilter: registeredServer.stamp.Props&stamps.ServerInformalPropertyNoFilter != 0,
|
||||||
Description: registeredServer.description,
|
Description: registeredServer.description,
|
||||||
}
|
}
|
||||||
if jsonOutput {
|
if jsonOutput {
|
||||||
|
@ -419,15 +420,15 @@ func (config *Config) printRegisteredServers(proxy *Proxy, jsonOutput bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config *Config) loadSources(proxy *Proxy) error {
|
func (config *Config) loadSources(proxy *Proxy) error {
|
||||||
requiredProps := ServerInformalProperties(0)
|
var requiredProps stamps.ServerInformalProperties
|
||||||
if config.SourceRequireDNSSEC {
|
if config.SourceRequireDNSSEC {
|
||||||
requiredProps |= ServerInformalPropertyDNSSEC
|
requiredProps |= stamps.ServerInformalPropertyDNSSEC
|
||||||
}
|
}
|
||||||
if config.SourceRequireNoLog {
|
if config.SourceRequireNoLog {
|
||||||
requiredProps |= ServerInformalPropertyNoLog
|
requiredProps |= stamps.ServerInformalPropertyNoLog
|
||||||
}
|
}
|
||||||
if config.SourceRequireNoFilter {
|
if config.SourceRequireNoFilter {
|
||||||
requiredProps |= ServerInformalPropertyNoFilter
|
requiredProps |= stamps.ServerInformalPropertyNoFilter
|
||||||
}
|
}
|
||||||
for cfgSourceName, cfgSource := range config.SourcesConfig {
|
for cfgSourceName, cfgSource := range config.SourcesConfig {
|
||||||
if err := config.loadSource(proxy, requiredProps, cfgSourceName, &cfgSource); err != nil {
|
if err := config.loadSource(proxy, requiredProps, cfgSourceName, &cfgSource); err != nil {
|
||||||
|
@ -447,7 +448,7 @@ func (config *Config) loadSources(proxy *Proxy) error {
|
||||||
if len(staticConfig.Stamp) == 0 {
|
if len(staticConfig.Stamp) == 0 {
|
||||||
dlog.Fatalf("Missing stamp for the static [%s] definition", serverName)
|
dlog.Fatalf("Missing stamp for the static [%s] definition", serverName)
|
||||||
}
|
}
|
||||||
stamp, err := NewServerStampFromString(staticConfig.Stamp)
|
stamp, err := stamps.NewServerStampFromString(staticConfig.Stamp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -456,7 +457,7 @@ func (config *Config) loadSources(proxy *Proxy) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config *Config) loadSource(proxy *Proxy, requiredProps ServerInformalProperties, cfgSourceName string, cfgSource *SourceConfig) error {
|
func (config *Config) loadSource(proxy *Proxy, requiredProps stamps.ServerInformalProperties, cfgSourceName string, cfgSource *SourceConfig) error {
|
||||||
if len(cfgSource.URLs) == 0 {
|
if len(cfgSource.URLs) == 0 {
|
||||||
if len(cfgSource.URL) == 0 {
|
if len(cfgSource.URL) == 0 {
|
||||||
dlog.Debugf("Missing URLs for source [%s]", cfgSourceName)
|
dlog.Debugf("Missing URLs for source [%s]", cfgSourceName)
|
||||||
|
@ -492,23 +493,23 @@ func (config *Config) loadSource(proxy *Proxy, requiredProps ServerInformalPrope
|
||||||
if !includesName(config.ServerNames, registeredServer.name) {
|
if !includesName(config.ServerNames, registeredServer.name) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else if registeredServer.stamp.props&requiredProps != requiredProps {
|
} else if registeredServer.stamp.Props&requiredProps != requiredProps {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if config.SourceIPv4 || config.SourceIPv6 {
|
if config.SourceIPv4 || config.SourceIPv6 {
|
||||||
isIPv4, isIPv6 := true, false
|
isIPv4, isIPv6 := true, false
|
||||||
if registeredServer.stamp.proto == StampProtoTypeDoH {
|
if registeredServer.stamp.Proto == stamps.StampProtoTypeDoH {
|
||||||
isIPv4, isIPv6 = true, true
|
isIPv4, isIPv6 = true, true
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(registeredServer.stamp.serverAddrStr, "[") {
|
if strings.HasPrefix(registeredServer.stamp.ServerAddrStr, "[") {
|
||||||
isIPv4, isIPv6 = false, true
|
isIPv4, isIPv6 = false, true
|
||||||
}
|
}
|
||||||
if !(config.SourceIPv4 == isIPv4 || config.SourceIPv6 == isIPv6) {
|
if !(config.SourceIPv4 == isIPv4 || config.SourceIPv6 == isIPv6) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !((config.SourceDNSCrypt && registeredServer.stamp.proto == StampProtoTypeDNSCrypt) ||
|
if !((config.SourceDNSCrypt && registeredServer.stamp.Proto == stamps.StampProtoTypeDNSCrypt) ||
|
||||||
(config.SourceDoH && registeredServer.stamp.proto == StampProtoTypeDoH)) {
|
(config.SourceDoH && registeredServer.stamp.Proto == stamps.StampProtoTypeDoH)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
dlog.Debugf("Adding [%s] to the set of wanted resolvers", registeredServer.name)
|
dlog.Debugf("Adding [%s] to the set of wanted resolvers", registeredServer.name)
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/jedisct1/dlog"
|
"github.com/jedisct1/dlog"
|
||||||
clocksmith "github.com/jedisct1/go-clocksmith"
|
clocksmith "github.com/jedisct1/go-clocksmith"
|
||||||
"golang.org/x/crypto/curve25519"
|
"golang.org/x/crypto/curve25519"
|
||||||
|
"github.com/jedisct1/dnscrypt-proxy/stamps"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Proxy struct {
|
type Proxy struct {
|
||||||
|
@ -274,7 +275,7 @@ func (proxy *Proxy) processIncomingQuery(serverInfo *ServerInfo, clientProto str
|
||||||
}
|
}
|
||||||
if len(response) == 0 {
|
if len(response) == 0 {
|
||||||
var ttl *uint32
|
var ttl *uint32
|
||||||
if serverInfo.Proto == StampProtoTypeDNSCrypt {
|
if serverInfo.Proto == stamps.StampProtoTypeDNSCrypt {
|
||||||
sharedKey, encryptedQuery, clientNonce, err := proxy.Encrypt(serverInfo, query, serverProto)
|
sharedKey, encryptedQuery, clientNonce, err := proxy.Encrypt(serverInfo, query, serverProto)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -289,7 +290,7 @@ func (proxy *Proxy) processIncomingQuery(serverInfo *ServerInfo, clientProto str
|
||||||
serverInfo.noticeFailure(proxy)
|
serverInfo.noticeFailure(proxy)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if serverInfo.Proto == StampProtoTypeDoH {
|
} else if serverInfo.Proto == stamps.StampProtoTypeDoH {
|
||||||
tid := TransactionID(query)
|
tid := TransactionID(query)
|
||||||
SetTransactionID(query, 0)
|
SetTransactionID(query, 0)
|
||||||
serverInfo.noticeBegin(proxy)
|
serverInfo.noticeBegin(proxy)
|
||||||
|
|
|
@ -17,31 +17,23 @@ import (
|
||||||
|
|
||||||
"github.com/VividCortex/ewma"
|
"github.com/VividCortex/ewma"
|
||||||
"github.com/jedisct1/dlog"
|
"github.com/jedisct1/dlog"
|
||||||
|
"github.com/jedisct1/dnscrypt-proxy/stamps"
|
||||||
"golang.org/x/crypto/ed25519"
|
"golang.org/x/crypto/ed25519"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
RTTEwmaDecay = 10.0
|
RTTEwmaDecay = 10.0
|
||||||
DefaultPort = 443
|
|
||||||
)
|
|
||||||
|
|
||||||
type ServerInformalProperties uint64
|
|
||||||
|
|
||||||
const (
|
|
||||||
ServerInformalPropertyDNSSEC = ServerInformalProperties(1) << 0
|
|
||||||
ServerInformalPropertyNoLog = ServerInformalProperties(1) << 1
|
|
||||||
ServerInformalPropertyNoFilter = ServerInformalProperties(1) << 2
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type RegisteredServer struct {
|
type RegisteredServer struct {
|
||||||
name string
|
name string
|
||||||
stamp ServerStamp
|
stamp stamps.ServerStamp
|
||||||
description string
|
description string
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServerInfo struct {
|
type ServerInfo struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
Proto StampProtoType
|
Proto stamps.StampProtoType
|
||||||
MagicQuery [8]byte
|
MagicQuery [8]byte
|
||||||
ServerPk [32]byte
|
ServerPk [32]byte
|
||||||
SharedKey [32]byte
|
SharedKey [32]byte
|
||||||
|
@ -77,7 +69,7 @@ type ServersInfo struct {
|
||||||
lbStrategy LBStrategy
|
lbStrategy LBStrategy
|
||||||
}
|
}
|
||||||
|
|
||||||
func (serversInfo *ServersInfo) registerServer(proxy *Proxy, name string, stamp ServerStamp) error {
|
func (serversInfo *ServersInfo) registerServer(proxy *Proxy, name string, stamp stamps.ServerStamp) error {
|
||||||
newRegisteredServer := RegisteredServer{name: name, stamp: stamp}
|
newRegisteredServer := RegisteredServer{name: name, stamp: stamp}
|
||||||
serversInfo.Lock()
|
serversInfo.Lock()
|
||||||
defer serversInfo.Unlock()
|
defer serversInfo.Unlock()
|
||||||
|
@ -91,7 +83,7 @@ func (serversInfo *ServersInfo) registerServer(proxy *Proxy, name string, stamp
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (serversInfo *ServersInfo) refreshServer(proxy *Proxy, name string, stamp ServerStamp) error {
|
func (serversInfo *ServersInfo) refreshServer(proxy *Proxy, name string, stamp stamps.ServerStamp) error {
|
||||||
serversInfo.Lock()
|
serversInfo.Lock()
|
||||||
defer serversInfo.Unlock()
|
defer serversInfo.Unlock()
|
||||||
previousIndex := -1
|
previousIndex := -1
|
||||||
|
@ -206,38 +198,38 @@ func (serversInfo *ServersInfo) getOne() *ServerInfo {
|
||||||
return serverInfo
|
return serverInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (serversInfo *ServersInfo) fetchServerInfo(proxy *Proxy, name string, stamp ServerStamp, isNew bool) (ServerInfo, error) {
|
func (serversInfo *ServersInfo) fetchServerInfo(proxy *Proxy, name string, stamp stamps.ServerStamp, isNew bool) (ServerInfo, error) {
|
||||||
if stamp.proto == StampProtoTypeDNSCrypt {
|
if stamp.Proto == stamps.StampProtoTypeDNSCrypt {
|
||||||
return serversInfo.fetchDNSCryptServerInfo(proxy, name, stamp, isNew)
|
return serversInfo.fetchDNSCryptServerInfo(proxy, name, stamp, isNew)
|
||||||
} else if stamp.proto == StampProtoTypeDoH {
|
} else if stamp.Proto == stamps.StampProtoTypeDoH {
|
||||||
return serversInfo.fetchDoHServerInfo(proxy, name, stamp, isNew)
|
return serversInfo.fetchDoHServerInfo(proxy, name, stamp, isNew)
|
||||||
}
|
}
|
||||||
return ServerInfo{}, errors.New("Unsupported protocol")
|
return ServerInfo{}, errors.New("Unsupported protocol")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (serversInfo *ServersInfo) fetchDNSCryptServerInfo(proxy *Proxy, name string, stamp ServerStamp, isNew bool) (ServerInfo, error) {
|
func (serversInfo *ServersInfo) fetchDNSCryptServerInfo(proxy *Proxy, name string, stamp stamps.ServerStamp, isNew bool) (ServerInfo, error) {
|
||||||
if len(stamp.serverPk) != ed25519.PublicKeySize {
|
if len(stamp.ServerPk) != ed25519.PublicKeySize {
|
||||||
serverPk, err := hex.DecodeString(strings.Replace(string(stamp.serverPk), ":", "", -1))
|
serverPk, err := hex.DecodeString(strings.Replace(string(stamp.ServerPk), ":", "", -1))
|
||||||
if err != nil || len(serverPk) != ed25519.PublicKeySize {
|
if err != nil || len(serverPk) != ed25519.PublicKeySize {
|
||||||
dlog.Fatalf("Unsupported public key for [%s]: [%s]", name, stamp.serverPk)
|
dlog.Fatalf("Unsupported public key for [%s]: [%s]", name, stamp.ServerPk)
|
||||||
}
|
}
|
||||||
dlog.Warnf("Public key [%s] shouldn't be hex-encoded any more", string(stamp.serverPk))
|
dlog.Warnf("Public key [%s] shouldn't be hex-encoded any more", string(stamp.ServerPk))
|
||||||
stamp.serverPk = serverPk
|
stamp.ServerPk = serverPk
|
||||||
}
|
}
|
||||||
certInfo, rtt, err := FetchCurrentDNSCryptCert(proxy, &name, proxy.mainProto, stamp.serverPk, stamp.serverAddrStr, stamp.providerName, isNew)
|
certInfo, rtt, err := FetchCurrentDNSCryptCert(proxy, &name, proxy.mainProto, stamp.ServerPk, stamp.ServerAddrStr, stamp.ProviderName, isNew)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ServerInfo{}, err
|
return ServerInfo{}, err
|
||||||
}
|
}
|
||||||
remoteUDPAddr, err := net.ResolveUDPAddr("udp", stamp.serverAddrStr)
|
remoteUDPAddr, err := net.ResolveUDPAddr("udp", stamp.ServerAddrStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ServerInfo{}, err
|
return ServerInfo{}, err
|
||||||
}
|
}
|
||||||
remoteTCPAddr, err := net.ResolveTCPAddr("tcp", stamp.serverAddrStr)
|
remoteTCPAddr, err := net.ResolveTCPAddr("tcp", stamp.ServerAddrStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ServerInfo{}, err
|
return ServerInfo{}, err
|
||||||
}
|
}
|
||||||
return ServerInfo{
|
return ServerInfo{
|
||||||
Proto: StampProtoTypeDNSCrypt,
|
Proto: stamps.StampProtoTypeDNSCrypt,
|
||||||
MagicQuery: certInfo.MagicQuery,
|
MagicQuery: certInfo.MagicQuery,
|
||||||
ServerPk: certInfo.ServerPk,
|
ServerPk: certInfo.ServerPk,
|
||||||
SharedKey: certInfo.SharedKey,
|
SharedKey: certInfo.SharedKey,
|
||||||
|
@ -250,18 +242,18 @@ func (serversInfo *ServersInfo) fetchDNSCryptServerInfo(proxy *Proxy, name strin
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (serversInfo *ServersInfo) fetchDoHServerInfo(proxy *Proxy, name string, stamp ServerStamp, isNew bool) (ServerInfo, error) {
|
func (serversInfo *ServersInfo) fetchDoHServerInfo(proxy *Proxy, name string, stamp stamps.ServerStamp, isNew bool) (ServerInfo, error) {
|
||||||
if len(stamp.serverAddrStr) > 0 {
|
if len(stamp.ServerAddrStr) > 0 {
|
||||||
addrStr := stamp.serverAddrStr
|
addrStr := stamp.ServerAddrStr
|
||||||
ipOnly := addrStr[:strings.LastIndex(addrStr, ":")]
|
ipOnly := addrStr[:strings.LastIndex(addrStr, ":")]
|
||||||
proxy.xTransport.cachedIPs.Lock()
|
proxy.xTransport.cachedIPs.Lock()
|
||||||
proxy.xTransport.cachedIPs.cache[stamp.providerName] = ipOnly
|
proxy.xTransport.cachedIPs.cache[stamp.ProviderName] = ipOnly
|
||||||
proxy.xTransport.cachedIPs.Unlock()
|
proxy.xTransport.cachedIPs.Unlock()
|
||||||
}
|
}
|
||||||
url := &url.URL{
|
url := &url.URL{
|
||||||
Scheme: "https",
|
Scheme: "https",
|
||||||
Host: stamp.providerName,
|
Host: stamp.ProviderName,
|
||||||
Path: stamp.path,
|
Path: stamp.Path,
|
||||||
}
|
}
|
||||||
body := []byte{
|
body := []byte{
|
||||||
0xca, 0xfe, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x29, 0x10, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
|
0xca, 0xfe, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x29, 0x10, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
|
||||||
|
@ -293,7 +285,7 @@ func (serversInfo *ServersInfo) fetchDoHServerInfo(proxy *Proxy, name string, st
|
||||||
} else {
|
} else {
|
||||||
dlog.Debugf("Advertised cert: [%s] [%x]", cert.Subject, h)
|
dlog.Debugf("Advertised cert: [%s] [%x]", cert.Subject, h)
|
||||||
}
|
}
|
||||||
for _, hash := range stamp.hashes {
|
for _, hash := range stamp.Hashes {
|
||||||
if len(hash) == len(wantedHash) {
|
if len(hash) == len(wantedHash) {
|
||||||
copy(wantedHash[:], hash)
|
copy(wantedHash[:], hash)
|
||||||
if h == wantedHash {
|
if h == wantedHash {
|
||||||
|
@ -306,7 +298,7 @@ func (serversInfo *ServersInfo) fetchDoHServerInfo(proxy *Proxy, name string, st
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !found && len(stamp.hashes) > 0 {
|
if !found && len(stamp.Hashes) > 0 {
|
||||||
return ServerInfo{}, fmt.Errorf("Certificate hash [%x] not found for [%s]", wantedHash, name)
|
return ServerInfo{}, fmt.Errorf("Certificate hash [%x] not found for [%s]", wantedHash, name)
|
||||||
}
|
}
|
||||||
respBody, err := ioutil.ReadAll(io.LimitReader(resp.Body, MaxHTTPBodyLength))
|
respBody, err := ioutil.ReadAll(io.LimitReader(resp.Body, MaxHTTPBodyLength))
|
||||||
|
@ -323,11 +315,11 @@ func (serversInfo *ServersInfo) fetchDoHServerInfo(proxy *Proxy, name string, st
|
||||||
dlog.Infof("[%s] OK (DoH) - rtt: %dms", name, rtt.Nanoseconds()/1000000)
|
dlog.Infof("[%s] OK (DoH) - rtt: %dms", name, rtt.Nanoseconds()/1000000)
|
||||||
}
|
}
|
||||||
return ServerInfo{
|
return ServerInfo{
|
||||||
Proto: StampProtoTypeDoH,
|
Proto: stamps.StampProtoTypeDoH,
|
||||||
Name: name,
|
Name: name,
|
||||||
Timeout: proxy.timeout,
|
Timeout: proxy.timeout,
|
||||||
URL: url,
|
URL: url,
|
||||||
HostName: stamp.providerName,
|
HostName: stamp.ProviderName,
|
||||||
initialRtt: int(rtt.Nanoseconds() / 1000000),
|
initialRtt: int(rtt.Nanoseconds() / 1000000),
|
||||||
useGet: useGet,
|
useGet: useGet,
|
||||||
}, nil
|
}, nil
|
||||||
|
|
|
@ -18,6 +18,7 @@ import (
|
||||||
|
|
||||||
"github.com/jedisct1/dlog"
|
"github.com/jedisct1/dlog"
|
||||||
"github.com/jedisct1/go-minisign"
|
"github.com/jedisct1/go-minisign"
|
||||||
|
"github.com/jedisct1/dnscrypt-proxy/stamps"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SourceFormat int
|
type SourceFormat int
|
||||||
|
@ -241,14 +242,14 @@ func (source *Source) parseV1(prefix string) ([]RegisteredServer, error) {
|
||||||
serverAddrStr := record[10]
|
serverAddrStr := record[10]
|
||||||
providerName := record[11]
|
providerName := record[11]
|
||||||
serverPkStr := record[12]
|
serverPkStr := record[12]
|
||||||
props := ServerInformalProperties(0)
|
props := stamps.ServerInformalProperties(0)
|
||||||
if strings.EqualFold(record[7], "yes") {
|
if strings.EqualFold(record[7], "yes") {
|
||||||
props |= ServerInformalPropertyDNSSEC
|
props |= stamps.ServerInformalPropertyDNSSEC
|
||||||
}
|
}
|
||||||
if strings.EqualFold(record[8], "yes") {
|
if strings.EqualFold(record[8], "yes") {
|
||||||
props |= ServerInformalPropertyNoLog
|
props |= stamps.ServerInformalPropertyNoLog
|
||||||
}
|
}
|
||||||
stamp, err := NewDNSCryptServerStampFromLegacy(serverAddrStr, serverPkStr, providerName, props)
|
stamp, err := stamps.NewDNSCryptServerStampFromLegacy(serverAddrStr, serverPkStr, providerName, props)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return registeredServers, err
|
return registeredServers, err
|
||||||
}
|
}
|
||||||
|
@ -301,7 +302,7 @@ func (source *Source) parseV2(prefix string) ([]RegisteredServer, error) {
|
||||||
if len(stampStr) < 8 {
|
if len(stampStr) < 8 {
|
||||||
return registeredServers, fmt.Errorf("Missing stamp for server [%s] in source from [%v]", name, source.urls)
|
return registeredServers, fmt.Errorf("Missing stamp for server [%s] in source from [%v]", name, source.urls)
|
||||||
}
|
}
|
||||||
stamp, err := NewServerStampFromString(stampStr)
|
stamp, err := stamps.NewServerStampFromString(stampStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return registeredServers, err
|
return registeredServers, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/jedisct1/dnscrypt-proxy/stamps"
|
||||||
"github.com/jedisct1/dlog"
|
"github.com/jedisct1/dlog"
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"golang.org/x/net/http2"
|
"golang.org/x/net/http2"
|
||||||
|
@ -83,7 +84,7 @@ func (xTransport *XTransport) rebuildTransport() {
|
||||||
ExpectContinueTimeout: timeout,
|
ExpectContinueTimeout: timeout,
|
||||||
MaxResponseHeaderBytes: 4096,
|
MaxResponseHeaderBytes: 4096,
|
||||||
DialContext: func(ctx context.Context, network, addrStr string) (net.Conn, error) {
|
DialContext: func(ctx context.Context, network, addrStr string) (net.Conn, error) {
|
||||||
host, port := ExtractHostAndPort(addrStr, DefaultPort)
|
host, port := ExtractHostAndPort(addrStr, stamps.DefaultPort)
|
||||||
ipOnly := host
|
ipOnly := host
|
||||||
xTransport.cachedIPs.RLock()
|
xTransport.cachedIPs.RLock()
|
||||||
cachedIP := xTransport.cachedIPs.cache[host]
|
cachedIP := xTransport.cachedIPs.cache[host]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package stamps
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
@ -14,6 +14,16 @@ import (
|
||||||
"golang.org/x/crypto/ed25519"
|
"golang.org/x/crypto/ed25519"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const DefaultPort = 443
|
||||||
|
|
||||||
|
type ServerInformalProperties uint64
|
||||||
|
|
||||||
|
const (
|
||||||
|
ServerInformalPropertyDNSSEC = ServerInformalProperties(1) << 0
|
||||||
|
ServerInformalPropertyNoLog = ServerInformalProperties(1) << 1
|
||||||
|
ServerInformalPropertyNoFilter = ServerInformalProperties(1) << 2
|
||||||
|
)
|
||||||
|
|
||||||
type StampProtoType uint8
|
type StampProtoType uint8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -36,13 +46,13 @@ func (stampProtoType *StampProtoType) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServerStamp struct {
|
type ServerStamp struct {
|
||||||
serverAddrStr string
|
ServerAddrStr string
|
||||||
serverPk []uint8
|
ServerPk []uint8
|
||||||
hashes [][]uint8
|
Hashes [][]uint8
|
||||||
providerName string
|
ProviderName string
|
||||||
path string
|
Path string
|
||||||
props ServerInformalProperties
|
Props ServerInformalProperties
|
||||||
proto StampProtoType
|
Proto StampProtoType
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDNSCryptServerStampFromLegacy(serverAddrStr string, serverPkStr string, providerName string, props ServerInformalProperties) (ServerStamp, error) {
|
func NewDNSCryptServerStampFromLegacy(serverAddrStr string, serverPkStr string, providerName string, props ServerInformalProperties) (ServerStamp, error) {
|
||||||
|
@ -54,11 +64,11 @@ func NewDNSCryptServerStampFromLegacy(serverAddrStr string, serverPkStr string,
|
||||||
return ServerStamp{}, fmt.Errorf("Unsupported public key: [%s]", serverPkStr)
|
return ServerStamp{}, fmt.Errorf("Unsupported public key: [%s]", serverPkStr)
|
||||||
}
|
}
|
||||||
return ServerStamp{
|
return ServerStamp{
|
||||||
serverAddrStr: serverAddrStr,
|
ServerAddrStr: serverAddrStr,
|
||||||
serverPk: serverPk,
|
ServerPk: serverPk,
|
||||||
providerName: providerName,
|
ProviderName: providerName,
|
||||||
props: props,
|
Props: props,
|
||||||
proto: StampProtoTypeDNSCrypt,
|
Proto: StampProtoTypeDNSCrypt,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,11 +94,11 @@ func NewServerStampFromString(stampStr string) (ServerStamp, error) {
|
||||||
// id(u8)=0x01 props addrLen(1) serverAddr pkStrlen(1) pkStr providerNameLen(1) providerName
|
// id(u8)=0x01 props addrLen(1) serverAddr pkStrlen(1) pkStr providerNameLen(1) providerName
|
||||||
|
|
||||||
func newDNSCryptServerStamp(bin []byte) (ServerStamp, error) {
|
func newDNSCryptServerStamp(bin []byte) (ServerStamp, error) {
|
||||||
stamp := ServerStamp{proto: StampProtoTypeDNSCrypt}
|
stamp := ServerStamp{Proto: StampProtoTypeDNSCrypt}
|
||||||
if len(bin) < 66 {
|
if len(bin) < 66 {
|
||||||
return stamp, errors.New("Stamp is too short")
|
return stamp, errors.New("Stamp is too short")
|
||||||
}
|
}
|
||||||
stamp.props = ServerInformalProperties(binary.LittleEndian.Uint64(bin[1:9]))
|
stamp.Props = ServerInformalProperties(binary.LittleEndian.Uint64(bin[1:9]))
|
||||||
binLen := len(bin)
|
binLen := len(bin)
|
||||||
pos := 9
|
pos := 9
|
||||||
|
|
||||||
|
@ -97,10 +107,10 @@ func newDNSCryptServerStamp(bin []byte) (ServerStamp, error) {
|
||||||
return stamp, errors.New("Invalid stamp")
|
return stamp, errors.New("Invalid stamp")
|
||||||
}
|
}
|
||||||
pos++
|
pos++
|
||||||
stamp.serverAddrStr = string(bin[pos : pos+len])
|
stamp.ServerAddrStr = string(bin[pos : pos+len])
|
||||||
pos += len
|
pos += len
|
||||||
if net.ParseIP(strings.TrimRight(strings.TrimLeft(stamp.serverAddrStr, "["), "]")) != nil {
|
if net.ParseIP(strings.TrimRight(strings.TrimLeft(stamp.ServerAddrStr, "["), "]")) != nil {
|
||||||
stamp.serverAddrStr = fmt.Sprintf("%s:%d", stamp.serverAddrStr, DefaultPort)
|
stamp.ServerAddrStr = fmt.Sprintf("%s:%d", stamp.ServerAddrStr, DefaultPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
len = int(bin[pos])
|
len = int(bin[pos])
|
||||||
|
@ -108,7 +118,7 @@ func newDNSCryptServerStamp(bin []byte) (ServerStamp, error) {
|
||||||
return stamp, errors.New("Invalid stamp")
|
return stamp, errors.New("Invalid stamp")
|
||||||
}
|
}
|
||||||
pos++
|
pos++
|
||||||
stamp.serverPk = bin[pos : pos+len]
|
stamp.ServerPk = bin[pos : pos+len]
|
||||||
pos += len
|
pos += len
|
||||||
|
|
||||||
len = int(bin[pos])
|
len = int(bin[pos])
|
||||||
|
@ -116,7 +126,7 @@ func newDNSCryptServerStamp(bin []byte) (ServerStamp, error) {
|
||||||
return stamp, errors.New("Invalid stamp")
|
return stamp, errors.New("Invalid stamp")
|
||||||
}
|
}
|
||||||
pos++
|
pos++
|
||||||
stamp.providerName = string(bin[pos : pos+len])
|
stamp.ProviderName = string(bin[pos : pos+len])
|
||||||
pos += len
|
pos += len
|
||||||
|
|
||||||
if pos != binLen {
|
if pos != binLen {
|
||||||
|
@ -128,11 +138,11 @@ func newDNSCryptServerStamp(bin []byte) (ServerStamp, error) {
|
||||||
// id(u8)=0x02 props addrLen(1) serverAddr hashLen(1) hash providerNameLen(1) providerName pathLen(1) path
|
// id(u8)=0x02 props addrLen(1) serverAddr hashLen(1) hash providerNameLen(1) providerName pathLen(1) path
|
||||||
|
|
||||||
func newDoHServerStamp(bin []byte) (ServerStamp, error) {
|
func newDoHServerStamp(bin []byte) (ServerStamp, error) {
|
||||||
stamp := ServerStamp{proto: StampProtoTypeDoH, hashes: [][]byte{}}
|
stamp := ServerStamp{Proto: StampProtoTypeDoH}
|
||||||
if len(bin) < 22 {
|
if len(bin) < 22 {
|
||||||
return stamp, errors.New("Stamp is too short")
|
return stamp, errors.New("Stamp is too short")
|
||||||
}
|
}
|
||||||
stamp.props = ServerInformalProperties(binary.LittleEndian.Uint64(bin[1:9]))
|
stamp.Props = ServerInformalProperties(binary.LittleEndian.Uint64(bin[1:9]))
|
||||||
binLen := len(bin)
|
binLen := len(bin)
|
||||||
pos := 9
|
pos := 9
|
||||||
|
|
||||||
|
@ -141,7 +151,7 @@ func newDoHServerStamp(bin []byte) (ServerStamp, error) {
|
||||||
return stamp, errors.New("Invalid stamp")
|
return stamp, errors.New("Invalid stamp")
|
||||||
}
|
}
|
||||||
pos++
|
pos++
|
||||||
stamp.serverAddrStr = string(bin[pos : pos+len])
|
stamp.ServerAddrStr = string(bin[pos : pos+len])
|
||||||
pos += len
|
pos += len
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
@ -152,7 +162,7 @@ func newDoHServerStamp(bin []byte) (ServerStamp, error) {
|
||||||
}
|
}
|
||||||
pos++
|
pos++
|
||||||
if len > 0 {
|
if len > 0 {
|
||||||
stamp.hashes = append(stamp.hashes, bin[pos:pos+len])
|
stamp.Hashes = append(stamp.Hashes, bin[pos:pos+len])
|
||||||
}
|
}
|
||||||
pos += len
|
pos += len
|
||||||
if vlen&0x80 != 0x80 {
|
if vlen&0x80 != 0x80 {
|
||||||
|
@ -165,7 +175,7 @@ func newDoHServerStamp(bin []byte) (ServerStamp, error) {
|
||||||
return stamp, errors.New("Invalid stamp")
|
return stamp, errors.New("Invalid stamp")
|
||||||
}
|
}
|
||||||
pos++
|
pos++
|
||||||
stamp.providerName = string(bin[pos : pos+len])
|
stamp.ProviderName = string(bin[pos : pos+len])
|
||||||
pos += len
|
pos += len
|
||||||
|
|
||||||
len = int(bin[pos])
|
len = int(bin[pos])
|
||||||
|
@ -173,24 +183,24 @@ func newDoHServerStamp(bin []byte) (ServerStamp, error) {
|
||||||
return stamp, errors.New("Invalid stamp")
|
return stamp, errors.New("Invalid stamp")
|
||||||
}
|
}
|
||||||
pos++
|
pos++
|
||||||
stamp.path = string(bin[pos : pos+len])
|
stamp.Path = string(bin[pos : pos+len])
|
||||||
pos += len
|
pos += len
|
||||||
|
|
||||||
if pos != binLen {
|
if pos != binLen {
|
||||||
return stamp, errors.New("Invalid stamp (garbage after end)")
|
return stamp, errors.New("Invalid stamp (garbage after end)")
|
||||||
}
|
}
|
||||||
|
|
||||||
if net.ParseIP(strings.TrimRight(strings.TrimLeft(stamp.serverAddrStr, "["), "]")) != nil {
|
if net.ParseIP(strings.TrimRight(strings.TrimLeft(stamp.ServerAddrStr, "["), "]")) != nil {
|
||||||
stamp.serverAddrStr = fmt.Sprintf("%s:%d", stamp.serverAddrStr, DefaultPort)
|
stamp.ServerAddrStr = fmt.Sprintf("%s:%d", stamp.ServerAddrStr, DefaultPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
return stamp, nil
|
return stamp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (stamp *ServerStamp) String() string {
|
func (stamp *ServerStamp) String() string {
|
||||||
if stamp.proto == StampProtoTypeDNSCrypt {
|
if stamp.Proto == StampProtoTypeDNSCrypt {
|
||||||
return stamp.dnsCryptString()
|
return stamp.dnsCryptString()
|
||||||
} else if stamp.proto == StampProtoTypeDoH {
|
} else if stamp.Proto == StampProtoTypeDoH {
|
||||||
return stamp.dohString()
|
return stamp.dohString()
|
||||||
}
|
}
|
||||||
dlog.Fatal("Unsupported protocol")
|
dlog.Fatal("Unsupported protocol")
|
||||||
|
@ -200,20 +210,20 @@ func (stamp *ServerStamp) String() string {
|
||||||
func (stamp *ServerStamp) dnsCryptString() string {
|
func (stamp *ServerStamp) dnsCryptString() string {
|
||||||
bin := make([]uint8, 9)
|
bin := make([]uint8, 9)
|
||||||
bin[0] = uint8(StampProtoTypeDNSCrypt)
|
bin[0] = uint8(StampProtoTypeDNSCrypt)
|
||||||
binary.LittleEndian.PutUint64(bin[1:9], uint64(stamp.props))
|
binary.LittleEndian.PutUint64(bin[1:9], uint64(stamp.Props))
|
||||||
|
|
||||||
serverAddrStr := stamp.serverAddrStr
|
serverAddrStr := stamp.ServerAddrStr
|
||||||
if strings.HasSuffix(serverAddrStr, ":"+strconv.Itoa(DefaultPort)) {
|
if strings.HasSuffix(serverAddrStr, ":"+strconv.Itoa(DefaultPort)) {
|
||||||
serverAddrStr = serverAddrStr[:len(serverAddrStr)-1-len(strconv.Itoa(DefaultPort))]
|
serverAddrStr = serverAddrStr[:len(serverAddrStr)-1-len(strconv.Itoa(DefaultPort))]
|
||||||
}
|
}
|
||||||
bin = append(bin, uint8(len(serverAddrStr)))
|
bin = append(bin, uint8(len(serverAddrStr)))
|
||||||
bin = append(bin, []uint8(serverAddrStr)...)
|
bin = append(bin, []uint8(serverAddrStr)...)
|
||||||
|
|
||||||
bin = append(bin, uint8(len(stamp.serverPk)))
|
bin = append(bin, uint8(len(stamp.ServerPk)))
|
||||||
bin = append(bin, stamp.serverPk...)
|
bin = append(bin, stamp.ServerPk...)
|
||||||
|
|
||||||
bin = append(bin, uint8(len(stamp.providerName)))
|
bin = append(bin, uint8(len(stamp.ProviderName)))
|
||||||
bin = append(bin, []uint8(stamp.providerName)...)
|
bin = append(bin, []uint8(stamp.ProviderName)...)
|
||||||
|
|
||||||
str := base64.RawURLEncoding.EncodeToString(bin)
|
str := base64.RawURLEncoding.EncodeToString(bin)
|
||||||
|
|
||||||
|
@ -223,17 +233,17 @@ func (stamp *ServerStamp) dnsCryptString() string {
|
||||||
func (stamp *ServerStamp) dohString() string {
|
func (stamp *ServerStamp) dohString() string {
|
||||||
bin := make([]uint8, 9)
|
bin := make([]uint8, 9)
|
||||||
bin[0] = uint8(StampProtoTypeDoH)
|
bin[0] = uint8(StampProtoTypeDoH)
|
||||||
binary.LittleEndian.PutUint64(bin[1:9], uint64(stamp.props))
|
binary.LittleEndian.PutUint64(bin[1:9], uint64(stamp.Props))
|
||||||
|
|
||||||
serverAddrStr := stamp.serverAddrStr
|
serverAddrStr := stamp.ServerAddrStr
|
||||||
if strings.HasSuffix(serverAddrStr, ":"+strconv.Itoa(DefaultPort)) {
|
if strings.HasSuffix(serverAddrStr, ":"+strconv.Itoa(DefaultPort)) {
|
||||||
serverAddrStr = serverAddrStr[:len(serverAddrStr)-1-len(strconv.Itoa(DefaultPort))]
|
serverAddrStr = serverAddrStr[:len(serverAddrStr)-1-len(strconv.Itoa(DefaultPort))]
|
||||||
}
|
}
|
||||||
bin = append(bin, uint8(len(serverAddrStr)))
|
bin = append(bin, uint8(len(serverAddrStr)))
|
||||||
bin = append(bin, []uint8(serverAddrStr)...)
|
bin = append(bin, []uint8(serverAddrStr)...)
|
||||||
|
|
||||||
last := len(stamp.hashes) - 1
|
last := len(stamp.Hashes) - 1
|
||||||
for i, hash := range stamp.hashes {
|
for i, hash := range stamp.Hashes {
|
||||||
vlen := len(hash)
|
vlen := len(hash)
|
||||||
if i < last {
|
if i < last {
|
||||||
vlen |= 0x80
|
vlen |= 0x80
|
||||||
|
@ -242,11 +252,11 @@ func (stamp *ServerStamp) dohString() string {
|
||||||
bin = append(bin, hash...)
|
bin = append(bin, hash...)
|
||||||
}
|
}
|
||||||
|
|
||||||
bin = append(bin, uint8(len(stamp.providerName)))
|
bin = append(bin, uint8(len(stamp.ProviderName)))
|
||||||
bin = append(bin, []uint8(stamp.providerName)...)
|
bin = append(bin, []uint8(stamp.ProviderName)...)
|
||||||
|
|
||||||
bin = append(bin, uint8(len(stamp.path)))
|
bin = append(bin, uint8(len(stamp.Path)))
|
||||||
bin = append(bin, []uint8(stamp.path)...)
|
bin = append(bin, []uint8(stamp.Path)...)
|
||||||
|
|
||||||
str := base64.RawURLEncoding.EncodeToString(bin)
|
str := base64.RawURLEncoding.EncodeToString(bin)
|
||||||
|
|
Loading…
Reference in New Issue