added the id field to ServerConn

This commit is contained in:
hyung-hwan 2024-12-03 00:55:19 +09:00
parent eef1941dea
commit b17f3af7ad
4 changed files with 164 additions and 51 deletions

View File

@ -149,10 +149,11 @@ func (ctl *client_ctl_client_conns) ServeHTTP(w http.ResponseWriter, req *http.R
var cts *ClientConn var cts *ClientConn
err = json.NewDecoder(req.Body).Decode(&s) err = json.NewDecoder(req.Body).Decode(&s)
if err != nil { if err != nil || s.ServerAddr == "" {
status_code = http.StatusBadRequest; w.WriteHeader(status_code) status_code = http.StatusBadRequest; w.WriteHeader(status_code)
goto done goto done
} }
cc.ServerAddr = s.ServerAddr cc.ServerAddr = s.ServerAddr
//cc.PeerAddrs = s.PeerAddrs //cc.PeerAddrs = s.PeerAddrs
cts, err = c.start_service(&cc) // TODO: this can be blocking. do we have to resolve addresses before calling this? also not good because resolution succeed or fail at each attempt. however ok as ServeHTTP itself is in a goroutine? cts, err = c.start_service(&cc) // TODO: this can be blocking. do we have to resolve addresses before calling this? also not good because resolution succeed or fail at each attempt. however ok as ServeHTTP itself is in a goroutine?
@ -196,6 +197,7 @@ func (ctl *client_ctl_client_conns_id) ServeHTTP(w http.ResponseWriter, req *htt
var conn_id string var conn_id string
var conn_nid uint64 var conn_nid uint64
var je *json.Encoder var je *json.Encoder
var cts *ClientConn
c = ctl.c c = ctl.c
je = json.NewEncoder(w) je = json.NewEncoder(w)
@ -209,13 +211,6 @@ func (ctl *client_ctl_client_conns_id) ServeHTTP(w http.ResponseWriter, req *htt
goto done goto done
} }
switch req.Method {
case http.MethodGet:
var r *ClientRoute
var jsp []json_out_client_route
var js *json_out_client_conn
var cts *ClientConn
cts = c.FindClientConnById(uint32(conn_nid)) cts = c.FindClientConnById(uint32(conn_nid))
if cts == nil { if cts == nil {
status_code = http.StatusNotFound; w.WriteHeader(status_code) status_code = http.StatusNotFound; w.WriteHeader(status_code)
@ -223,6 +218,12 @@ func (ctl *client_ctl_client_conns_id) ServeHTTP(w http.ResponseWriter, req *htt
goto done goto done
} }
switch req.Method {
case http.MethodGet:
var r *ClientRoute
var jsp []json_out_client_route
var js *json_out_client_conn
jsp = make([]json_out_client_route, 0) jsp = make([]json_out_client_route, 0)
cts.route_mtx.Lock() cts.route_mtx.Lock()
for _, r = range cts.route_map { for _, r = range cts.route_map {
@ -239,13 +240,9 @@ func (ctl *client_ctl_client_conns_id) ServeHTTP(w http.ResponseWriter, req *htt
if err = je.Encode(js); err != nil { goto oops } if err = je.Encode(js); err != nil { goto oops }
case http.MethodDelete: case http.MethodDelete:
err = c.RemoveClientConnById(uint32(conn_nid)) //c.RemoveClientConn(cts)
if err != nil { cts.ReqStop()
status_code = http.StatusNotFound; w.WriteHeader(status_code)
if err = je.Encode(json_errmsg{Text: err.Error()}); err != nil { goto oops }
} else {
status_code = http.StatusNoContent; w.WriteHeader(status_code) status_code = http.StatusNoContent; w.WriteHeader(status_code)
}
default: default:
status_code = http.StatusBadRequest; w.WriteHeader(status_code) status_code = http.StatusBadRequest; w.WriteHeader(status_code)

View File

@ -951,7 +951,7 @@ func (c *Client) RemoveClientConn(cts *ClientConn) error {
fmt.Printf("REMOVEDDDDDD CONNECTION FROM %s total servers %d\n", cts.cfg.ServerAddr, len(c.cts_map_by_addr)) fmt.Printf("REMOVEDDDDDD CONNECTION FROM %s total servers %d\n", cts.cfg.ServerAddr, len(c.cts_map_by_addr))
c.cts_mtx.Unlock() c.cts_mtx.Unlock()
c.ReqStop() cts.ReqStop()
return nil return nil
} }

View File

@ -2,6 +2,7 @@ package hodu
import "encoding/json" import "encoding/json"
import "net/http" import "net/http"
import "strconv"
type json_out_server_conn struct { type json_out_server_conn struct {
@ -86,5 +87,68 @@ oops:
// ------------------------------------ // ------------------------------------
func (ctl *server_ctl_server_conns_id) ServeHTTP(w http.ResponseWriter, req *http.Request) { func (ctl *server_ctl_server_conns_id) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// TODO: var s *Server
var status_code int
var err error
var je *json.Encoder
var conn_id string
var conn_nid uint64
var cts *ServerConn
s = ctl.s
je = json.NewEncoder(w)
conn_id = req.PathValue("conn_id")
conn_nid, err = strconv.ParseUint(conn_id, 10, 32)
if err != nil {
status_code = http.StatusBadRequest; w.WriteHeader(status_code)
if err = je.Encode(json_errmsg{Text: "wrong connection id - " + conn_id}); err != nil { goto oops }
goto done
}
cts = s.FindServerConnById(uint32(conn_nid))
if cts == nil {
status_code = http.StatusNotFound; w.WriteHeader(status_code)
if err = je.Encode(json_errmsg{Text: "non-existent connection id - " + conn_id}); err != nil { goto oops }
goto done
}
switch req.Method {
case http.MethodGet:
var r *ServerRoute
var jsp []json_out_server_route
var js *json_out_server_conn
jsp = make([]json_out_server_route, 0)
cts.route_mtx.Lock()
for _, r = range cts.route_map {
jsp = append(jsp, json_out_server_route{
Id: r.id,
ClientPeerAddr: r.ptc_addr,
ServerPeerListenAddr: r.laddr.String(),
})
}
js = &json_out_server_conn{Id: cts.id, ClientAddr: cts.caddr.String(), ServerAddr: cts.local_addr.String(), Routes: jsp}
cts.route_mtx.Unlock()
status_code = http.StatusOK; w.WriteHeader(status_code)
if err = je.Encode(js); err != nil { goto oops }
case http.MethodDelete:
//s.RemoveServerConn(cts)
cts.ReqStop()
status_code = http.StatusNoContent; w.WriteHeader(status_code)
default:
status_code = http.StatusBadRequest; w.WriteHeader(status_code)
}
done:
s.log.Write("", LOG_DEBUG, "[%s] %s %s %d", req.RemoteAddr, req.Method, req.URL.String(), status_code) // TODO: time taken
return
oops:
s.log.Write("", LOG_ERROR, "[%s] %s %s - %s", req.RemoteAddr, req.Method, req.URL.String(), err.Error())
return
} }

View File

@ -19,7 +19,8 @@ import "google.golang.org/grpc/stats"
const PTS_LIMIT = 8192 const PTS_LIMIT = 8192
type ServerConnMap = map[net.Addr]*ServerConn type ServerConnMapByAddr = map[net.Addr]*ServerConn
type ServerConnMap = map[uint32]*ServerConn
type ServerPeerConnMap = map[uint32]*ServerPeerConn type ServerPeerConnMap = map[uint32]*ServerPeerConn
type ServerRouteMap = map[uint32]*ServerRoute type ServerRouteMap = map[uint32]*ServerRoute
@ -43,6 +44,7 @@ type Server struct {
cts_mtx sync.Mutex cts_mtx sync.Mutex
cts_map ServerConnMap cts_map ServerConnMap
cts_map_by_addr ServerConnMapByAddr
cts_wg sync.WaitGroup cts_wg sync.WaitGroup
gs *grpc.Server gs *grpc.Server
@ -56,6 +58,7 @@ type Server struct {
type ServerConn struct { type ServerConn struct {
svr *Server svr *Server
id uint32 id uint32
lid string // for logging
caddr net.Addr // client address that created this structure caddr net.Addr // client address that created this structure
local_addr net.Addr local_addr net.Addr
pss *GuardedPacketStreamServer pss *GuardedPacketStreamServer
@ -390,7 +393,7 @@ func (cts *ServerConn) receive_from_stream(wg *sync.WaitGroup) {
if err != nil { if err != nil {
cts.svr.log.Write("", LOG_ERROR, "Failed to add server route for client %s peer %s", cts.caddr, x.Route.AddrStr) cts.svr.log.Write("", LOG_ERROR, "Failed to add server route for client %s peer %s", cts.caddr, x.Route.AddrStr)
} else { } else {
cts.svr.log.Write("", LOG_INFO, "Added server route(id=%d) for client %s peer %s", r.id, cts.caddr, x.Route.AddrStr) cts.svr.log.Write("", LOG_INFO, "Added server route(id=%d) for client %s peer %s to cts(id=%d)", r.id, cts.caddr, x.Route.AddrStr, cts.id)
err = cts.pss.Send(MakeRouteStartedPacket(r.id, x.Route.Proto, r.laddr.String())) err = cts.pss.Send(MakeRouteStartedPacket(r.id, x.Route.Proto, r.laddr.String()))
if err != nil { if err != nil {
r.ReqStop() r.ReqStop()
@ -728,7 +731,8 @@ func NewServer(ctx context.Context, ctl_addr string, laddrs []string, logger Log
s.tlscfg = tlscfg s.tlscfg = tlscfg
s.ext_svcs = make([]Service, 0, 1) s.ext_svcs = make([]Service, 0, 1)
s.cts_map = make(ServerConnMap) // TODO: make it configurable... s.cts_map = make(ServerConnMap)
s.cts_map_by_addr = make(ServerConnMapByAddr)
s.stop_chan = make(chan bool, 8) s.stop_chan = make(chan bool, 8)
s.stop_req.Store(false) s.stop_req.Store(false)
/* /*
@ -750,9 +754,9 @@ func NewServer(ctx context.Context, ctl_addr string, laddrs []string, logger Log
s.ctl_mux = http.NewServeMux() s.ctl_mux = http.NewServeMux()
cwd, _ = os.Getwd() cwd, _ = os.Getwd()
s.ctl_mux.Handle(s.ctl_prefix + "/ui/", http.StripPrefix(s.ctl_prefix, http.FileServer(http.Dir(cwd)))) // TODO: proper directory. it must not use the current working directory... s.ctl_mux.Handle(s.ctl_prefix + "/ui/", http.StripPrefix(s.ctl_prefix, http.FileServer(http.Dir(cwd)))) // TODO: proper directory. it must not use the current working directory...
//s.ctl_mux.HandleFunc(s.ctl_prefix + "/ws/tty", websocket.Handler(server_ws_tty).ServeHTTP)
s.ctl_mux.Handle(s.ctl_prefix + "/ws/tty", new_server_ctl_ws_tty(&s)) s.ctl_mux.Handle(s.ctl_prefix + "/ws/tty", new_server_ctl_ws_tty(&s))
s.ctl_mux.Handle(s.ctl_prefix + "/server-conns", &server_ctl_server_conns{s: &s}) s.ctl_mux.Handle(s.ctl_prefix + "/server-conns", &server_ctl_server_conns{s: &s})
s.ctl_mux.Handle(s.ctl_prefix + "/server-conns/{conn_id}", &server_ctl_server_conns_id{s: &s})
s.ctl = &http.Server{ s.ctl = &http.Server{
Addr: ctl_addr, Addr: ctl_addr,
@ -872,6 +876,7 @@ func (s *Server) ReqStop() {
func (s *Server) AddNewServerConn(remote_addr *net.Addr, local_addr *net.Addr, pss Hodu_PacketStreamServer) (*ServerConn, error) { func (s *Server) AddNewServerConn(remote_addr *net.Addr, local_addr *net.Addr, pss Hodu_PacketStreamServer) (*ServerConn, error) {
var cts ServerConn var cts ServerConn
var id uint32
var ok bool var ok bool
cts.svr = s cts.svr = s
@ -886,11 +891,21 @@ func (s *Server) AddNewServerConn(remote_addr *net.Addr, local_addr *net.Addr, p
s.cts_mtx.Lock() s.cts_mtx.Lock()
defer s.cts_mtx.Unlock() defer s.cts_mtx.Unlock()
_, ok = s.cts_map[cts.caddr] id = rand.Uint32()
for {
_, ok = s.cts_map[id]
if !ok { break }
id++
}
cts.id = id
cts.lid = fmt.Sprintf("%d", id) // id in string used for logging
_, ok = s.cts_map_by_addr[cts.caddr]
if ok { if ok {
return nil, fmt.Errorf("existing client - %s", cts.caddr.String()) return nil, fmt.Errorf("existing client - %s", cts.caddr.String())
} }
s.cts_map[cts.caddr] = &cts s.cts_map_by_addr[cts.caddr] = &cts
s.cts_map[id] = &cts;
s.log.Write("", LOG_DEBUG, "Added client connection from %s", cts.caddr.String()) s.log.Write("", LOG_DEBUG, "Added client connection from %s", cts.caddr.String())
return &cts, nil return &cts, nil
} }
@ -906,25 +921,62 @@ func (s *Server) ReqStopAllServerConns() {
} }
} }
func (s *Server) RemoveServerConn(cts *ServerConn) { func (s *Server) RemoveServerConn(cts *ServerConn) error {
var conn *ServerConn
var ok bool
s.cts_mtx.Lock() s.cts_mtx.Lock()
delete(s.cts_map, cts.caddr)
s.log.Write("", LOG_DEBUG, "Removed client connection from %s", cts.caddr.String()) conn, ok = s.cts_map[cts.id]
if !ok {
s.cts_mtx.Unlock() s.cts_mtx.Unlock()
return fmt.Errorf("non-existent connection id - %d", cts.id)
}
if conn != cts {
s.cts_mtx.Unlock()
return fmt.Errorf("non-existent connection id - %d", cts.id)
} }
func (s *Server) RemoveServerConnByAddr(addr net.Addr) { delete(s.cts_map, cts.id)
delete(s.cts_map_by_addr, cts.caddr)
s.cts_mtx.Unlock()
cts.ReqStop()
return nil
}
func (s *Server) RemoveServerConnByAddr(addr net.Addr) error {
var cts *ServerConn
var ok bool
s.cts_mtx.Lock()
cts, ok = s.cts_map_by_addr[addr]
if !ok {
s.cts_mtx.Unlock()
return fmt.Errorf("non-existent connection address - %s", addr.String())
}
delete(s.cts_map, cts.id)
delete(s.cts_map_by_addr, cts.caddr)
s.cts_mtx.Unlock()
cts.ReqStop()
return nil
}
func (s* Server) FindServerConnById(id uint32) *ServerConn {
var cts *ServerConn var cts *ServerConn
var ok bool var ok bool
s.cts_mtx.Lock() s.cts_mtx.Lock()
defer s.cts_mtx.Unlock() defer s.cts_mtx.Unlock()
cts, ok = s.cts_map[addr] cts, ok = s.cts_map[id]
if ok { if !ok {
delete(s.cts_map, cts.caddr) return nil
cts.ReqStop()
} }
return cts
} }
func (s *Server) FindServerConnByAddr(addr net.Addr) *ServerConn { func (s *Server) FindServerConnByAddr(addr net.Addr) *ServerConn {
@ -934,7 +986,7 @@ func (s *Server) FindServerConnByAddr(addr net.Addr) *ServerConn {
s.cts_mtx.Lock() s.cts_mtx.Lock()
defer s.cts_mtx.Unlock() defer s.cts_mtx.Unlock()
cts, ok = s.cts_map[addr] cts, ok = s.cts_map_by_addr[addr]
if !ok { if !ok {
return nil return nil
} }