Skip to content

Commit

Permalink
Calculate node name by using network stack
Browse files Browse the repository at this point in the history
  • Loading branch information
buraksezer committed Apr 1, 2020
1 parent f3cbc64 commit 1d844be
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 22 deletions.
19 changes: 5 additions & 14 deletions cmd/olricd/server/memberlist.go
Expand Up @@ -15,12 +15,11 @@
package server

import (
"fmt"
"net"
"os"
"time"

"github.com/buraksezer/olric/config"
"github.com/buraksezer/olric/internal/network"
m "github.com/hashicorp/memberlist"
)

Expand Down Expand Up @@ -100,19 +99,11 @@ func newMemberlistConf(c *Config) (*m.Config, error) {
if c.Memberlist.AdvertiseAddr != nil {
mc.AdvertiseAddr = *c.Memberlist.AdvertiseAddr
} else {
if ip := net.ParseIP(mc.BindAddr); ip != nil {
mc.AdvertiseAddr = ip.String()
} else {
ans, err := net.LookupIP(mc.BindAddr)
if err != nil {
return nil, err
}
// Fail early.
if len(ans) == 0 {
return nil, fmt.Errorf("no IP address found for %s", mc.BindAddr)
}
mc.AdvertiseAddr = ans[0].String()
advertiseAddr, err := network.ParseOrLookupIP(mc.BindAddr)
if err != nil {
return nil, err
}
mc.AdvertiseAddr = advertiseAddr.String()
}
if c.Memberlist.AdvertisePort != nil {
mc.AdvertisePort = *c.Memberlist.AdvertisePort
Expand Down
1 change: 1 addition & 0 deletions go.mod
Expand Up @@ -8,6 +8,7 @@ require (
github.com/cespare/xxhash v1.1.0
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e
github.com/hashicorp/go-multierror v1.0.0
github.com/hashicorp/go-sockaddr v1.0.0
github.com/hashicorp/logutils v1.0.0
github.com/hashicorp/memberlist v0.1.5
github.com/pkg/errors v0.9.1
Expand Down
9 changes: 4 additions & 5 deletions internal/discovery/discovery.go
@@ -1,4 +1,4 @@
// Copyright 2018-2019 Burak Sezer
// Copyright 2018-2020 Burak Sezer
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -123,16 +123,15 @@ func (d *Discovery) DecodeNodeMeta(buf []byte) (Member, error) {
// New creates a new memberlist with a proper configuration and returns a new Discovery instance along with it.
func New(log *flog.Logger, c *config.Config) (*Discovery, error) {
// Calculate host's identity. It's useful to compare hosts.
name := net.JoinHostPort(c.BindAddr, strconv.Itoa(c.BindPort))
birthdate := time.Now().UnixNano()

buf := make([]byte, 8+len(name))
buf := make([]byte, 8+len(c.MemberlistConfig.Name))
binary.BigEndian.PutUint64(buf, uint64(birthdate))
buf = append(buf, []byte(name)...)
buf = append(buf, []byte(c.MemberlistConfig.Name)...)

id := c.Hasher.Sum64(buf)
host := &Member{
Name: name,
Name: c.MemberlistConfig.Name,
ID: id,
Birthdate: birthdate,
}
Expand Down
78 changes: 78 additions & 0 deletions internal/network/ip.go
@@ -0,0 +1,78 @@
// Copyright 2018-2020 Burak Sezer
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/*Package network provides utility functions for network-related tasks*/
package network

import (
"fmt"
"net"

"github.com/hashicorp/go-sockaddr"
)

func ParseOrLookupIP(addr string) (net.IP, error) {
if ip := net.ParseIP(addr); ip != nil {
return ip, nil
}

ans, err := net.LookupIP(addr)
if err != nil {
return nil, err
}
// Fail early.
if len(ans) == 0 {
return nil, fmt.Errorf("no IP address found for %s", addr)
}
return ans[0], nil
}

func AddrToIP(addr string) (net.IP, error) {
ip, err := ParseOrLookupIP(addr)
if err != nil {
return nil, err
}
ipStr := ip.String()

var advertiseAddr net.IP
if ipStr == "0.0.0.0" {
// Otherwise, if we're not bound to a specific IP, let's
// use a suitable private IP address.
var err error
ipStr, err = sockaddr.GetPrivateIP()
if err != nil {
return nil, fmt.Errorf("failed to get interface addresses: %v", err)
}
if ipStr == "" {
return nil, fmt.Errorf("no private IP address found, and explicit IP not provided")
}

advertiseAddr = net.ParseIP(ipStr)
if advertiseAddr == nil {
return nil, fmt.Errorf("failed to parse advertise address: %q", ipStr)
}
} else {
// If they've supplied an address, use that.
advertiseAddr = net.ParseIP(ipStr)
if advertiseAddr == nil {
return nil, fmt.Errorf("failed to parse advertise address %q", ipStr)
}

// Ensure IPv4 conversion if necessary.
if ip4 := advertiseAddr.To4(); ip4 != nil {
advertiseAddr = ip4
}
}
return advertiseAddr, nil
}
12 changes: 9 additions & 3 deletions olric.go
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/buraksezer/olric/internal/discovery"
"github.com/buraksezer/olric/internal/flog"
"github.com/buraksezer/olric/internal/locker"
"github.com/buraksezer/olric/internal/network"
"github.com/buraksezer/olric/internal/protocol"
"github.com/buraksezer/olric/internal/storage"
"github.com/buraksezer/olric/internal/transport"
Expand Down Expand Up @@ -234,9 +235,12 @@ func New(c *config.Config) (*Olric, error) {
return nil, err
}

bindAddr, err := network.AddrToIP(c.BindAddr)
if err != nil {
return nil, err
}
// Set the name of this node in the cluster
name := net.JoinHostPort(c.BindAddr, strconv.Itoa(c.BindPort))
c.MemberlistConfig.Name = name
c.MemberlistConfig.Name = net.JoinHostPort(bindAddr.String(), strconv.Itoa(c.BindPort))

cfg := consistent.Config{
Hasher: c.Hasher,
Expand Down Expand Up @@ -266,7 +270,7 @@ func New(c *config.Config) (*Olric, error) {
}

db := &Olric{
name: name,
name: c.MemberlistConfig.Name,
ctx: ctx,
cancel: cancel,
log: flogger,
Expand Down Expand Up @@ -485,6 +489,8 @@ func (db *Olric) Start() error {
db.config.WriteQuorum)
}

db.log.V(2).Printf("[INFO] Node name in the cluster: %s", db.name)

// Start periodic tasks.
db.wg.Add(2)
go db.updateRoutingPeriodically()
Expand Down

0 comments on commit 1d844be

Please sign in to comment.