small refactor*
This commit is contained in:
parent
b6b541e050
commit
24a4d30275
232 changed files with 2164 additions and 1906 deletions
server/pkg/go-nfs
102
server/pkg/go-nfs/server.go
Normal file
102
server/pkg/go-nfs/server.go
Normal file
|
@ -0,0 +1,102 @@
|
|||
package nfs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Server is a handle to the listening NFS server.
|
||||
type Server struct {
|
||||
Handler
|
||||
ID [8]byte
|
||||
}
|
||||
|
||||
// RegisterMessageHandler registers a handler for a specific
|
||||
// XDR procedure.
|
||||
func RegisterMessageHandler(protocol uint32, proc uint32, handler HandleFunc) error {
|
||||
if registeredHandlers == nil {
|
||||
registeredHandlers = make(map[registeredHandlerID]HandleFunc)
|
||||
}
|
||||
for k := range registeredHandlers {
|
||||
if k.protocol == protocol && k.proc == proc {
|
||||
return errors.New("already registered")
|
||||
}
|
||||
}
|
||||
id := registeredHandlerID{protocol, proc}
|
||||
registeredHandlers[id] = handler
|
||||
return nil
|
||||
}
|
||||
|
||||
// HandleFunc represents a handler for a specific protocol message.
|
||||
type HandleFunc func(ctx context.Context, w *response, userHandler Handler) error
|
||||
|
||||
// TODO: store directly as a uint64 for more efficient lookups
|
||||
type registeredHandlerID struct {
|
||||
protocol uint32
|
||||
proc uint32
|
||||
}
|
||||
|
||||
var registeredHandlers map[registeredHandlerID]HandleFunc
|
||||
|
||||
// Serve listens on the provided listener port for incoming client requests.
|
||||
func (s *Server) Serve(l net.Listener) error {
|
||||
defer l.Close()
|
||||
if bytes.Equal(s.ID[:], []byte{0, 0, 0, 0, 0, 0, 0, 0}) {
|
||||
if _, err := rand.Reader.Read(s.ID[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
var tempDelay time.Duration
|
||||
|
||||
for {
|
||||
conn, err := l.Accept()
|
||||
if err != nil {
|
||||
if ne, ok := err.(net.Error); ok && ne.Timeout() {
|
||||
if tempDelay == 0 {
|
||||
tempDelay = 5 * time.Millisecond
|
||||
} else {
|
||||
tempDelay *= 2
|
||||
}
|
||||
if max := 1 * time.Second; tempDelay > max {
|
||||
tempDelay = max
|
||||
}
|
||||
time.Sleep(tempDelay)
|
||||
continue
|
||||
}
|
||||
return err
|
||||
}
|
||||
tempDelay = 0
|
||||
c := s.newConn(conn)
|
||||
go c.serve()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) newConn(nc net.Conn) *conn {
|
||||
c := &conn{
|
||||
Server: s,
|
||||
Conn: nc,
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// TODO: keep an immutable map for each server instance to have less
|
||||
// chance of races.
|
||||
func (s *Server) handlerFor(prog uint32, proc uint32) HandleFunc {
|
||||
for k, v := range registeredHandlers {
|
||||
if k.protocol == prog && k.proc == proc {
|
||||
return v
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Serve is a singleton listener paralleling http.Serve
|
||||
func Serve(l net.Listener, handler Handler) error {
|
||||
srv := &Server{Handler: handler}
|
||||
return srv.Serve(l)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue