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
err = json.NewDecoder(req.Body).Decode(&s)
if err != nil {
if err != nil || s.ServerAddr == "" {
status_code = http.StatusBadRequest; w.WriteHeader(status_code)
goto done
}
cc.ServerAddr = s.ServerAddr
//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?
@ -196,6 +197,7 @@ func (ctl *client_ctl_client_conns_id) ServeHTTP(w http.ResponseWriter, req *htt
var conn_id string
var conn_nid uint64
var je *json.Encoder
var cts *ClientConn
c = ctl.c
je = json.NewEncoder(w)
@ -209,13 +211,6 @@ func (ctl *client_ctl_client_conns_id) ServeHTTP(w http.ResponseWriter, req *htt
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))
if cts == nil {
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
}
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)
cts.route_mtx.Lock()
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 }
case http.MethodDelete:
err = c.RemoveClientConnById(uint32(conn_nid))
if err != nil {
status_code = http.StatusNotFound; w.WriteHeader(status_code)
if err = je.Encode(json_errmsg{Text: err.Error()}); err != nil { goto oops }
} else {
//c.RemoveClientConn(cts)
cts.ReqStop()
status_code = http.StatusNoContent; w.WriteHeader(status_code)
}
default:
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))
c.cts_mtx.Unlock()
c.ReqStop()
cts.ReqStop()
return nil
}

View File

@ -2,6 +2,7 @@ package hodu
import "encoding/json"
import "net/http"
import "strconv"
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) {
// 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
type ServerConnMap = map[net.Addr]*ServerConn
type ServerConnMapByAddr = map[net.Addr]*ServerConn
type ServerConnMap = map[uint32]*ServerConn
type ServerPeerConnMap = map[uint32]*ServerPeerConn
type ServerRouteMap = map[uint32]*ServerRoute
@ -43,6 +44,7 @@ type Server struct {
cts_mtx sync.Mutex
cts_map ServerConnMap
cts_map_by_addr ServerConnMapByAddr
cts_wg sync.WaitGroup
gs *grpc.Server
@ -56,6 +58,7 @@ type Server struct {
type ServerConn struct {
svr *Server
id uint32
lid string // for logging
caddr net.Addr // client address that created this structure
local_addr net.Addr
pss *GuardedPacketStreamServer
@ -390,7 +393,7 @@ func (cts *ServerConn) receive_from_stream(wg *sync.WaitGroup) {
if err != nil {
cts.svr.log.Write("", LOG_ERROR, "Failed to add server route for client %s peer %s", cts.caddr, x.Route.AddrStr)
} 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()))
if err != nil {
r.ReqStop()
@ -728,7 +731,8 @@ func NewServer(ctx context.Context, ctl_addr string, laddrs []string, logger Log
s.tlscfg = tlscfg
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_req.Store(false)
/*
@ -750,9 +754,9 @@ func NewServer(ctx context.Context, ctl_addr string, laddrs []string, logger Log
s.ctl_mux = http.NewServeMux()
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.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 + "/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{
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) {
var cts ServerConn
var id uint32
var ok bool
cts.svr = s
@ -886,11 +891,21 @@ func (s *Server) AddNewServerConn(remote_addr *net.Addr, local_addr *net.Addr, p
s.cts_mtx.Lock()
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 {
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())
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()
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()
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 ok bool
s.cts_mtx.Lock()
defer s.cts_mtx.Unlock()
cts, ok = s.cts_map[addr]
if ok {
delete(s.cts_map, cts.caddr)
cts.ReqStop()
cts, ok = s.cts_map[id]
if !ok {
return nil
}
return cts
}
func (s *Server) FindServerConnByAddr(addr net.Addr) *ServerConn {
@ -934,7 +986,7 @@ func (s *Server) FindServerConnByAddr(addr net.Addr) *ServerConn {
s.cts_mtx.Lock()
defer s.cts_mtx.Unlock()
cts, ok = s.cts_map[addr]
cts, ok = s.cts_map_by_addr[addr]
if !ok {
return nil
}