func (m *Memberlist) LocalNode() *Node {
	m.nodeLock.RLock()
	defer m.nodeLock.RUnlock()
	state := m.nodeMap[m.config.Name]
	return &state.Node
}
LocalNode is used to return the local Node
package memberlist
import (
	"fmt"
	"log"
	"net"
	"os"
	"strconv"
	"sync"
	"time"
)
type Memberlist struct {
	config         *Config
	shutdown       bool
	shutdownCh     chan struct{}
	leave          bool
	leaveBroadcast chan struct{}
	udpListener *net.UDPConn
	tcpListener *net.TCPListener
	handoff     chan msgHandoff
	sequenceNum uint32  
	incarnation uint32  
	nodeLock sync.RWMutex
	nodes    []*nodeState           
	nodeMap  map[string]*nodeState  
	tickerLock sync.Mutex
	tickers    []*time.Ticker
	stopTick   chan struct{}
	probeIndex int
	ackLock     sync.Mutex
	ackHandlers map[uint32]*ackHandler
	broadcasts *TransmitLimitedQueue
	startStopLock sync.Mutex
	logger *log.Logger
}
func newMemberlist(conf *Config) (*Memberlist, error) {
	if conf.ProtocolVersion < ProtocolVersionMin {
		return nil, fmt.Errorf("Protocol version '%d' too low. Must be in range: [%d, %d]",
			conf.ProtocolVersion, ProtocolVersionMin, ProtocolVersionMax)
	} else if conf.ProtocolVersion > ProtocolVersionMax {
		return nil, fmt.Errorf("Protocol version '%d' too high. Must be in range: [%d, %d]",
			conf.ProtocolVersion, ProtocolVersionMin, ProtocolVersionMax)
	}
	if len(conf.SecretKey) > 0 {
		if conf.Keyring == nil {
			keyring, err := NewKeyring(nil, conf.SecretKey)
			if err != nil {
				return nil, err
			}
			conf.Keyring = keyring
		} else {
			if err := conf.Keyring.AddKey(conf.SecretKey); err != nil {
				return nil, err
			}
			if err := conf.Keyring.UseKey(conf.SecretKey); err != nil {
				return nil, err
			}
		}
	}
	tcpAddr := &net.TCPAddr{IP: net.ParseIP(conf.BindAddr), Port: conf.BindPort}
	tcpLn, err := net.ListenTCP("tcp", tcpAddr)
	if err != nil {
		return nil, fmt.Errorf("Failed to start TCP listener. Err: %s", err)
	}
	udpAddr := &net.UDPAddr{IP: net.ParseIP(conf.BindAddr), Port: conf.BindPort}
	udpLn, err := net.ListenUDP("udp", udpAddr)
	if err != nil {
		tcpLn.Close()
		return nil, fmt.Errorf("Failed to start UDP listener. Err: %s", err)
	}
	setUDPRecvBuf(udpLn)
	if conf.LogOutput == nil {
		conf.LogOutput = os.Stderr
	}
	logger := log.New(conf.LogOutput, "", log.LstdFlags)
	m := &Memberlist{
		config:         conf,
		shutdownCh:     make(chan struct{}),
		leaveBroadcast: make(chan struct{}, 1),
		udpListener:    udpLn,
		tcpListener:    tcpLn,
		handoff:        make(chan msgHandoff, 1024),
		nodeMap:        make(map[string]*nodeState),
		ackHandlers:    make(map[uint32]*ackHandler),
		broadcasts:     &TransmitLimitedQueue{RetransmitMult: conf.RetransmitMult},
		logger:         logger,
	}
	m.broadcasts.NumNodes = func() int { return len(m.nodes) }
	go m.tcpListen()
	go m.udpListen()
	go m.udpHandler()
	return m, nil
}
func Create(conf *Config) (*Memberlist, error) {
	m, err := newMemberlist(conf)
	if err != nil {
		return nil, err
	}
	if err := m.setAlive(); err != nil {
		m.Shutdown()
		return nil, err
	}
	m.schedule()
	return m, nil
}
func (m *Memberlist) Join(existing []string) (int, error) {
	numSuccess := 0
	var retErr error
	for _, exist := range existing {
		addrs, port, err := m.resolveAddr(exist)
		if err != nil {
			m.logger.Printf("[WARN] memberlist: Failed to resolve %s: %v", exist, err)
			retErr = err
			continue
		}
		for _, addr := range addrs {
			if err := m.pushPullNode(addr, port, true); err != nil {
				retErr = err
				continue
			}
			numSuccess++
		}
	}
	if numSuccess > 0 {
		retErr = nil
	}
	return numSuccess, retErr
}
func (m *Memberlist) resolveAddr(hostStr string) ([][]byte, uint16, error) {
	ips := make([][]byte, 0)
	port := uint16(0)
	host, sport, err := net.SplitHostPort(hostStr)
	if ae, ok := err.(*net.AddrError); ok && ae.Err == "missing port in address" {
		port = uint16(m.config.BindPort)
		host = hostStr
	} else if err != nil {
		return ips, port, err
	} else if lport, err := strconv.ParseUint(sport, 10, 16); err != nil {
		return ips, port, err
	} else {
		port = uint16(lport)
	}
	if ip := net.ParseIP(host); ip == nil {
		if pre, err := net.LookupIP(host); err == nil {
			for _, ip := range pre {
				ips = append(ips, ip)
			}
		} else {
			return ips, port, err
		}
	} else {
		ips = append(ips, ip)
	}
	return ips, port, nil
}
func (m *Memberlist) setAlive() error {
	var advertiseAddr []byte
	var advertisePort int
	if m.config.AdvertiseAddr != "" {
		ip := net.ParseIP(m.config.AdvertiseAddr)
		if ip == nil {
			return fmt.Errorf("Failed to parse advertise address!")
		}
		if ip4 := ip.To4(); ip4 != nil {
			ip = ip4
		}
		advertiseAddr = ip
		advertisePort = m.config.AdvertisePort
	} else {
		if m.config.BindAddr == "0.0.0.0" {
			addresses, err := net.InterfaceAddrs()
			if err != nil {
				return fmt.Errorf("Failed to get interface addresses! Err: %v", err)
			}
			for _, rawAddr := range addresses {
				var ip net.IP
				switch addr := rawAddr.(type) {
				case *net.IPAddr:
					ip = addr.IP
				case *net.IPNet:
					ip = addr.IP
				default:
					continue
				}
				if ip.To4() == nil {
					continue
				}
				if !isPrivateIP(ip.String()) {
					continue
				}
				advertiseAddr = ip
				break
			}
			if advertiseAddr == nil {
				return fmt.Errorf("No private IP address found, and explicit IP not provided")
			}
		} else {
			addr := m.tcpListener.Addr().(*net.TCPAddr)
			advertiseAddr = addr.IP
		}
		advertisePort = m.config.BindPort
	}
	addrStr := net.IP(advertiseAddr).String()
	if !isPrivateIP(addrStr) && !isLoopbackIP(addrStr) && !m.config.EncryptionEnabled() {
		m.logger.Printf("[WARN] memberlist: Binding to public address without encryption!")
	}
	var meta []byte
	if m.config.Delegate != nil {
		meta = m.config.Delegate.NodeMeta(MetaMaxSize)
		if len(meta) > MetaMaxSize {
			panic("Node meta data provided is longer than the limit")
		}
	}
	a := alive{
		Incarnation: m.nextIncarnation(),
		Node:        m.config.Name,
		Addr:        advertiseAddr,
		Port:        uint16(advertisePort),
		Meta:        meta,
		Vsn: []uint8{
			ProtocolVersionMin, ProtocolVersionMax, m.config.ProtocolVersion,
			m.config.DelegateProtocolMin, m.config.DelegateProtocolMax,
			m.config.DelegateProtocolVersion,
		},
	}
	m.aliveNode(&a, nil, true)
	return nil
}