Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
neoppod
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
1
Issues
1
List
Boards
Labels
Milestones
Merge Requests
2
Merge Requests
2
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
neoppod
Commits
0f745d66
Commit
0f745d66
authored
Apr 27, 2018
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
7087d5f4
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
244 additions
and
0 deletions
+244
-0
go/xcommon/xnet/lonet/lonet.go
go/xcommon/xnet/lonet/lonet.go
+151
-0
go/xcommon/xnet/lonet/registry.go
go/xcommon/xnet/lonet/registry.go
+93
-0
No files found.
go/xcommon/xnet/lonet/lonet.go
0 → 100644
View file @
0f745d66
// Copyright (C) 2018 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your
// option) any later version, as published by the Free Software Foundation.
//
// You can also Link and Combine this program with other software covered by
// the terms of any of the Free Software licenses or any of the Open Source
// Initiative approved licenses and Convey the resulting work. Corresponding
// source of such a combination shall include the source code for all other
// software used.
//
// This program is distributed WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// See COPYING file for full licensing terms.
// See https://www.nexedi.com/licensing for rationale and options.
// FIXME kill dup from pipenet!
// Package lonet provides TCP network on top of localhost TCP loopback.
//
// XXX write that several hosts could be created with different names (virtual
// address) and that port allocation is virtual too (e.g. α:1 could correspond to 127.0.0.1:4567)
//
// Example:
//
// net := lonet.New("")
// h1 := net.Host("abc")
// h2 := net.Host("def")
//
// // XXX inject 127.0.0.1 to example...
// // starts listening on address "abc:10" (which gets mapped to "127.0.0.1:xxx")
// l, err := h1.Listen(":10")
// go func() {
// csrv, err := l.Accept() // csrv will have LocalAddr "abc:10"
// }()
// ccli, err := h2.Dial("abc:10") // ccli will have RemoteAddr "def:10"
//
// Lonet is similar to pipenet, but since it works via OS TCP stack it could be
// handy for testing networked application when there are several OS-level
// processes involved.
package
lonet
/*
const NetPrefix = "lonet" // lonet package creates only "lonet*" networks
// Addr represents address of a lonet endpoint.
type Addr struct {
Net string // full network name, e.g. "lonet"
Host string // name of host access point on the network
Port int // port on host
}
// Network implements ... XXX
type Network struct {
// name of this network under "lonet" namespace -> e.g. ""
// full network name will be reported as "lonet"+name
name string
// big network lock for everything dynamic under Network
// (e.g. Host.socketv too) XXX
mu sync.Mutex
hostMap map[string]*Host
}
// Host represents named access point on Network
type Host struct {
network *Network
name string
// NOTE protected by Network.mu
socketv []*socket // port -> listener | conn ; [0] is always nil
}
var _ xnet.Networker = (*Host)(nil)
// socket represents one endpoint entry on Network
// it can be either already connected or listening
type socket struct {
host *Host // host/port this socket is bound to
port int
conn *conn // connection endpoint is here if != nil
listener *listener // listener is waiting here if != nil
}
// conn represents one endpoint of connection created under Network
type conn struct {
socket *socket
peersk *socket // the other side of this connection
net.Conn
closeOnce sync.Once
}
// XXX listener
// XXX dialReq
// ----------------------------------------
// New creates new lonet Network.
//
// name is name of this network under "lonet" namespace, e.g. "α" will give full network name "lonetα".
//
// New does not check whether network name provided is unique.
func New(name string) *Network {
return &Network{name: name, hostMap: make(map[string]*Host)}
}
// Host returns network access point by name.
//
// If there was no such host before it creates new one.
func (n *Network) Host(name string) *Host {
n.mu.Lock()
defer n.mu.Unlock()
host := n.hostMap[name]
if host == nil {
host = &Host{network: n, name: name}
n.hostMap[name] = host
}
return host
}
// resolveAddr resolves addr on the network from the host point of view
// must be called with Network.mu held
func (h *Host) resolveAddr(addr string) (host *Host, port int, err error) {
a, err := h.network.ParseAddr(addr)
if err != nil {
return nil, 0, err
}
// local host if host name omitted
if a.Host == "" {
a.Host = h.name
}
host = h.network.hostMap[a.Host]
if host == nil {
return nil, 0, &net.AddrError{Err: "no such host", Addr: addr}
}
return host, a.Port, nil
}
*/
go/xcommon/xnet/lonet/registry.go
0 → 100644
View file @
0f745d66
// Copyright (C) 2018 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your
// option) any later version, as published by the Free Software Foundation.
//
// You can also Link and Combine this program with other software covered by
// the terms of any of the Free Software licenses or any of the Open Source
// Initiative approved licenses and Convey the resulting work. Corresponding
// source of such a combination shall include the source code for all other
// software used.
//
// This program is distributed WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// See COPYING file for full licensing terms.
// See https://www.nexedi.com/licensing for rationale and options.
package
lonet
// registry of network hosts
import
(
"errors"
"fmt"
)
// registry represents access to lonet network registry.
//
// The registry holds information about hosts available on the network and
// for each host its OS listening address. Whenever host α needs to establish
// connection to address on host β, it queries the registry for β and further
// talks to β on that address. Correspondingly when a host joins the network,
// it announces itself to the registry so that other hosts could see it.
//
// The registry could be implemented in several ways, for example:
//
// - dedicated network server,
// - hosts broadcasting information to each other similar to ARP,
// - shared memory or file,
// - ...
type
registry
interface
{
// Announce announces host to registry.
//
// The host is named as hostname on lonet network and is listening for
// incoming lonet protocol connections on OS-level osladdr address.
//
// Returned error, if !nil, is *registryError with .Err describing the
// error cause:
//
// - errRegistryDown if registry cannot be accessed XXX (and its underlying cause?)
// - errHostDup
// - some other error indicating e.g. IO problem.
Announce
(
hostname
,
osladdr
string
)
error
// Query queries registry for host.
//
// If successful - it returns OS-level network address to connect to
// the host via lonet protocol handshake.
//
// Returned error, if !nil, is *registryError with .Err describing the
// error cause:
//
// - errRegistryDown ... XXX
// - errNoHost if hostname was not announced to registry,
// - some other error indicating e.g. IO problem.
Query
(
hostname
string
)
(
osladdr
string
,
_
error
)
}
var
errRegistryDown
=
errors
.
New
(
"registry is down"
)
var
errNoHost
=
errors
.
New
(
"no such host"
)
var
errHostDup
=
errors
.
New
(
"host already registered"
)
type
registryError
struct
{
// XXX name of the network?
Registry
string
// name of the registry
Op
string
// operation that failed
Args
interface
{}
// operation arguments, if any
Err
error
// actual error that occurred during the operation
}
func
(
e
*
registryError
)
Error
()
string
{
s
:=
e
.
Registry
+
": "
+
e
.
Op
if
e
.
Args
!=
nil
{
s
+=
fmt
.
Sprintf
(
" %s"
,
e
.
Args
)
}
s
+=
": "
+
e
.
Err
.
Error
()
return
s
}
func
(
e
*
registryError
)
Cause
()
error
{
return
e
.
Err
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment