dnscrypt-proxy/dnscrypt-proxy/common.go

137 lines
2.6 KiB
Go
Raw Normal View History

package main
import (
2018-01-09 19:47:24 +01:00
"encoding/binary"
"errors"
"net"
2018-01-17 17:03:42 +01:00
"strconv"
2018-01-17 16:06:30 +01:00
"strings"
"unicode"
)
type CryptoConstruction uint16
const (
UndefinedConstruction CryptoConstruction = iota
XSalsa20Poly1305
XChacha20Poly1305
)
2018-01-10 16:01:29 +01:00
const (
ClientMagicLen = 8
)
2018-02-04 11:31:54 +01:00
const (
MaxHTTPBodyLength = 4000000
)
var (
CertMagic = [4]byte{0x44, 0x4e, 0x53, 0x43}
ServerMagic = [8]byte{0x72, 0x36, 0x66, 0x6e, 0x76, 0x57, 0x6a, 0x38}
2018-01-10 03:04:13 +01:00
MinDNSPacketSize = 12 + 5
2018-01-09 13:27:03 +01:00
MaxDNSPacketSize = 4096
2018-01-09 16:40:37 +01:00
MaxDNSUDPPacketSize = 1252
InitialMinQuestionSize = 256
)
2018-01-09 19:47:24 +01:00
func PrefixWithSize(packet []byte) ([]byte, error) {
2018-01-31 08:38:22 +01:00
packetLen := len(packet)
if packetLen > 0xffff {
2018-01-09 19:47:24 +01:00
return packet, errors.New("Packet too large")
}
packet = append(append(packet, 0), 0)
copy(packet[2:], packet[:len(packet)-2])
binary.BigEndian.PutUint16(packet[0:2], uint16(len(packet)-2))
return packet, nil
}
func ReadPrefixed(conn *net.TCPConn) ([]byte, error) {
buf := make([]byte, 2+MaxDNSPacketSize)
packetLength, pos := -1, 0
for {
readnb, err := (*conn).Read(buf[pos:])
if err != nil {
return buf, err
}
pos += readnb
if pos >= 2 && packetLength < 0 {
packetLength = int(binary.BigEndian.Uint16(buf[0:2]))
if packetLength > MaxDNSPacketSize-1 {
return buf, errors.New("Packet too large")
}
if packetLength < MinDNSPacketSize {
return buf, errors.New("Packet too short")
}
2018-01-09 19:47:24 +01:00
}
if pos >= 2+packetLength {
return buf[2 : 2+packetLength], nil
2018-01-09 19:47:24 +01:00
}
}
}
2018-01-09 16:40:37 +01:00
func Min(a, b int) int {
if a < b {
return a
}
return b
}
func Max(a, b int) int {
if a > b {
return a
}
return b
}
func MinF(a, b float64) float64 {
if a < b {
return a
}
return b
}
func MaxF(a, b float64) float64 {
if a > b {
return a
}
return b
}
func StringReverse(s string) string {
r := []rune(s)
for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
r[i], r[j] = r[j], r[i]
}
return string(r)
}
2018-01-17 16:06:30 +01:00
func StringTwoFields(str string) (string, string, bool) {
if len(str) < 3 {
return "", "", false
}
pos := strings.IndexFunc(str, unicode.IsSpace)
if pos == -1 {
return "", "", false
}
a, b := strings.TrimFunc(str[:pos], unicode.IsSpace), strings.TrimFunc(str[pos+1:], unicode.IsSpace)
if len(a) == 0 || len(b) == 0 {
return a, b, false
}
return a, b, true
}
2018-01-17 17:03:42 +01:00
func StringQuote(str string) string {
str = strconv.QuoteToGraphic(str)
return str[1 : len(str)-1]
}
func ExtractPort(str string, defaultPort int) int {
port := defaultPort
if idx := strings.LastIndex(str, ":"); idx >= 0 && idx < len(str)-1 {
if portX, err := strconv.Atoi(str[idx+1:]); err == nil {
port = portX
}
}
return port
}