Parsing ipv6 addresses

This commit is contained in:
Shlomi Noach 2018-09-16 11:44:52 +03:00
parent 1e067e5a37
commit 49b80df27b
3 changed files with 29 additions and 14 deletions

View File

@ -739,7 +739,7 @@ func (this *Migrator) initiateInspector() (err error) {
log.Infof("Master found to be %+v", *this.migrationContext.ApplierConnectionConfig.ImpliedKey) log.Infof("Master found to be %+v", *this.migrationContext.ApplierConnectionConfig.ImpliedKey)
} else { } else {
// Forced master host. // Forced master host.
key, err := mysql.ParseRawInstanceKeyLoose(this.migrationContext.AssumeMasterHostname) key, err := mysql.ParseInstanceKey(this.migrationContext.AssumeMasterHostname)
if err != nil { if err != nil {
return err return err
} }

View File

@ -7,6 +7,7 @@ package mysql
import ( import (
"fmt" "fmt"
"regexp"
"strconv" "strconv"
"strings" "strings"
) )
@ -15,6 +16,12 @@ const (
DefaultInstancePort = 3306 DefaultInstancePort = 3306
) )
var (
ipv4HostPortRegexp = regexp.MustCompile("^([^:]+):([0-9]+)$")
ipv4HostRegexp = regexp.MustCompile("^([^:]+)$")
ipv6HostPortRegexp = regexp.MustCompile("^\\[(.+)\\]:([0-9]+)$") // e.g. [2001:db8:1f70::999:de8:7648:6e8]:3308
)
// InstanceKey is an instance indicator, identified by hostname and port // InstanceKey is an instance indicator, identified by hostname and port
type InstanceKey struct { type InstanceKey struct {
Hostname string Hostname string
@ -25,25 +32,33 @@ const detachHint = "//"
// ParseInstanceKey will parse an InstanceKey from a string representation such as 127.0.0.1:3306 // ParseInstanceKey will parse an InstanceKey from a string representation such as 127.0.0.1:3306
func NewRawInstanceKey(hostPort string) (*InstanceKey, error) { func NewRawInstanceKey(hostPort string) (*InstanceKey, error) {
tokens := strings.SplitN(hostPort, ":", 2) hostname := ""
if len(tokens) != 2 { port := ""
return nil, fmt.Errorf("Cannot parse InstanceKey from %s. Expected format is host:port", hostPort) if submatch := ipv4HostPortRegexp.FindStringSubmatch(hostPort); len(submatch) > 0 {
hostname = submatch[1]
port = submatch[2]
} else if submatch := ipv4HostRegexp.FindStringSubmatch(hostPort); len(submatch) > 0 {
hostname = submatch[1]
} else if submatch := ipv6HostPortRegexp.FindStringSubmatch(hostPort); len(submatch) > 0 {
hostname = submatch[1]
port = submatch[2]
} else {
return nil, fmt.Errorf("Cannot parse address: %s", hostPort)
} }
instanceKey := &InstanceKey{Hostname: tokens[0]} instanceKey := &InstanceKey{Hostname: hostname, Port: DefaultInstancePort}
var err error if port != "" {
if instanceKey.Port, err = strconv.Atoi(tokens[1]); err != nil { var err error
return instanceKey, fmt.Errorf("Invalid port: %s", tokens[1]) if instanceKey.Port, err = strconv.Atoi(port); err != nil {
return instanceKey, fmt.Errorf("Invalid port: %s", port)
}
} }
return instanceKey, nil return instanceKey, nil
} }
// ParseRawInstanceKeyLoose will parse an InstanceKey from a string representation such as 127.0.0.1:3306. // ParseInstanceKey will parse an InstanceKey from a string representation such as 127.0.0.1:3306.
// The port part is optional; there will be no name resolve // The port part is optional; there will be no name resolve
func ParseRawInstanceKeyLoose(hostPort string) (*InstanceKey, error) { func ParseInstanceKey(hostPort string) (*InstanceKey, error) {
if !strings.Contains(hostPort, ":") {
return &InstanceKey{Hostname: hostPort, Port: DefaultInstancePort}, nil
}
return NewRawInstanceKey(hostPort) return NewRawInstanceKey(hostPort)
} }

View File

@ -92,7 +92,7 @@ func (this *InstanceKeyMap) ReadCommaDelimitedList(list string) error {
} }
tokens := strings.Split(list, ",") tokens := strings.Split(list, ",")
for _, token := range tokens { for _, token := range tokens {
key, err := ParseRawInstanceKeyLoose(token) key, err := ParseInstanceKey(token)
if err != nil { if err != nil {
return err return err
} }