refactored functions in client-ctl.go to use common functions

This commit is contained in:
hyung-hwan 2025-02-22 10:08:57 +09:00
parent 429bb6cd63
commit 7363986737
4 changed files with 115 additions and 149 deletions

View File

@ -24,7 +24,8 @@ import "unsafe"
*/
type json_in_client_conn struct {
ServerAddrs []string `json:"server-addrs"`
ServerAddrs []string `json:"server-addrs"` // multiple addresses for round-robin connection re-attempts
ClientToken string `json:"client-token"`
}
type json_in_client_route struct {
@ -97,8 +98,6 @@ type client_ctl_token struct {
type client_ctl_client_conns struct {
client_ctl
//c *Client
//id string
}
type client_ctl_client_conns_id struct {
@ -268,18 +267,18 @@ func (ctl *client_ctl_client_conns) ServeHTTP(w http.ResponseWriter, req *http.R
// as it's tricky to handle erroneous cases in creating the client routes
// after hacing connected to the server. therefore, the json_in_client_conn
// type contains a server address field only.
var s json_in_client_conn
var in_cc json_in_client_conn
var cc ClientConnConfig
var cts *ClientConn
err = json.NewDecoder(req.Body).Decode(&s)
if err != nil || len(s.ServerAddrs) <= 0 {
err = json.NewDecoder(req.Body).Decode(&in_cc)
if err != nil || len(in_cc.ServerAddrs) <= 0 {
status_code = WriteEmptyRespHeader(w, http.StatusBadRequest)
goto done
}
cc.ServerAddrs = s.ServerAddrs
//cc.PeerAddrs = s.PeerAddrs
cc.ServerAddrs = in_cc.ServerAddrs
cc.ClientToken = in_cc.ClientToken
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?
if err != nil {
status_code = WriteJsonRespHeader(w, http.StatusInternalServerError)
@ -315,28 +314,19 @@ oops:
func (ctl *client_ctl_client_conns_id) ServeHTTP(w http.ResponseWriter, req *http.Request) (int, error) {
var c *Client
var status_code int
var err error
var conn_id string
var conn_nid uint64
var je *json.Encoder
var cts *ClientConn
var err error
c = ctl.c
je = json.NewEncoder(w)
conn_id = req.PathValue("conn_id")
conn_nid, err = strconv.ParseUint(conn_id, 10, int(unsafe.Sizeof(ConnId(0)) * 8))
cts, err = c.FindClientConnByIdStr(conn_id)
if err != nil {
status_code = WriteJsonRespHeader(w, http.StatusBadRequest)
je.Encode(JsonErrmsg{Text: "wrong connection id - " + conn_id})
goto oops
}
cts = c.FindClientConnById(ConnId(conn_nid))
if cts == nil {
status_code = WriteJsonRespHeader(w, http.StatusNotFound)
je.Encode(JsonErrmsg{Text: "non-existent connection id - " + conn_id})
je.Encode(JsonErrmsg{Text: err.Error()})
goto oops
}
@ -394,28 +384,19 @@ oops:
func (ctl *client_ctl_client_conns_id_routes) ServeHTTP(w http.ResponseWriter, req *http.Request) (int, error) {
var c *Client
var status_code int
var err error
var conn_id string
var conn_nid uint64
var je *json.Encoder
var cts *ClientConn
var err error
c = ctl.c
je = json.NewEncoder(w)
conn_id = req.PathValue("conn_id")
conn_nid, err = strconv.ParseUint(conn_id, 10, int(unsafe.Sizeof(ConnId(0)) * 8))
cts, err = c.FindClientConnByIdStr(conn_id)
if err != nil {
status_code = WriteJsonRespHeader(w, http.StatusBadRequest)
je.Encode(JsonErrmsg{Text: "wrong connection id - " + conn_id })
goto oops
}
cts = c.FindClientConnById(ConnId(conn_nid))
if cts == nil {
status_code = WriteJsonRespHeader(w, http.StatusNotFound)
je.Encode(JsonErrmsg{Text: "non-existent connection id - " + conn_id})
je.Encode(JsonErrmsg{Text: err.Error()})
goto oops
}
@ -518,45 +499,21 @@ oops:
func (ctl *client_ctl_client_conns_id_routes_id) ServeHTTP(w http.ResponseWriter, req *http.Request) (int, error) {
var c *Client
var status_code int
var err error
var conn_id string
var route_id string
var conn_nid uint64
var route_nid uint64
var je *json.Encoder
var cts *ClientConn
var r *ClientRoute
var err error
c = ctl.c
je = json.NewEncoder(w)
conn_id = req.PathValue("conn_id")
route_id = req.PathValue("route_id")
conn_nid, err = strconv.ParseUint(conn_id, 10, int(unsafe.Sizeof(ConnId(0)) * 8))
r, err = c.FindClientRouteByIdStr(conn_id, route_id)
if err != nil {
status_code = WriteJsonRespHeader(w, http.StatusBadRequest)
je.Encode(JsonErrmsg{Text: "wrong connection id - " + conn_id})
goto oops
}
route_nid, err = strconv.ParseUint(route_id, 10, int(unsafe.Sizeof(RouteId(0)) * 8))
if err != nil {
status_code = WriteJsonRespHeader(w, http.StatusBadRequest)
je.Encode(JsonErrmsg{Text: "wrong route id - " + route_id})
goto oops
}
cts = c.FindClientConnById(ConnId(conn_nid))
if cts == nil {
status_code = WriteJsonRespHeader(w, http.StatusNotFound)
je.Encode(JsonErrmsg{Text: "non-existent connection id - " + conn_id})
goto oops
}
r = cts.FindClientRouteById(RouteId(route_nid))
if r == nil {
status_code = WriteJsonRespHeader(w, http.StatusNotFound)
je.Encode(JsonErrmsg{Text: "non-existent route id - " + route_id})
je.Encode(JsonErrmsg{Text: err.Error()})
goto oops
}
@ -730,37 +687,21 @@ oops:
func (ctl *client_ctl_client_conns_id_routes_id_peers) ServeHTTP(w http.ResponseWriter, req *http.Request) (int, error) {
var c *Client
var status_code int
var err error
var conn_id string
var route_id string
var conn_nid uint64
var route_nid uint64
var je *json.Encoder
var r *ClientRoute
var err error
c = ctl.c
je = json.NewEncoder(w)
conn_id = req.PathValue("conn_id")
route_id = req.PathValue("route_id")
conn_nid, err = strconv.ParseUint(conn_id, 10, int(unsafe.Sizeof(ConnId(0)) * 8))
r, err = c.FindClientRouteByIdStr(conn_id, route_id)
if err != nil {
status_code = WriteJsonRespHeader(w, http.StatusBadRequest)
je.Encode(JsonErrmsg{Text: "wrong connection id - " + conn_id})
goto oops
}
route_nid, err = strconv.ParseUint(route_id, 10, int(unsafe.Sizeof(RouteId(0)) * 8))
if err != nil {
status_code = WriteJsonRespHeader(w, http.StatusBadRequest)
je.Encode(JsonErrmsg{Text: "wrong route id - " + route_id})
goto oops
}
r = c.FindClientRouteById(ConnId(conn_nid), RouteId(route_nid))
if r == nil {
status_code = WriteJsonRespHeader(w, http.StatusNotFound)
je.Encode(JsonErrmsg{Text: "non-existent connection/route id - " + conn_id + "/" + route_id})
je.Encode(JsonErrmsg{Text: err.Error()})
goto oops
}
@ -805,15 +746,12 @@ oops:
func (ctl *client_ctl_client_conns_id_routes_id_peers_id) ServeHTTP(w http.ResponseWriter, req *http.Request) (int, error) {
var c *Client
var status_code int
var err error
var conn_id string
var route_id string
var peer_id string
var conn_nid uint64
var route_nid uint64
var peer_nid uint64
var je *json.Encoder
var p *ClientPeerConn
var err error
c = ctl.c
je = json.NewEncoder(w)
@ -821,30 +759,10 @@ func (ctl *client_ctl_client_conns_id_routes_id_peers_id) ServeHTTP(w http.Respo
conn_id = req.PathValue("conn_id")
route_id = req.PathValue("route_id")
peer_id = req.PathValue("peer_id")
conn_nid, err = strconv.ParseUint(conn_id, 10, int(unsafe.Sizeof(ConnId(0)) * 8))
p, err = c.FindClientPeerConnByIdStr(conn_id, route_id, peer_id)
if err != nil {
status_code = WriteJsonRespHeader(w, http.StatusBadRequest)
je.Encode(JsonErrmsg{Text: "wrong connection id - " + conn_id})
goto oops
}
route_nid, err = strconv.ParseUint(route_id, 10, int(unsafe.Sizeof(RouteId(0)) * 8))
if err != nil {
status_code = WriteJsonRespHeader(w, http.StatusBadRequest)
je.Encode(JsonErrmsg{Text: "wrong route id - " + route_id})
goto oops
}
peer_nid, err = strconv.ParseUint(peer_id, 10, int(unsafe.Sizeof(ConnId(0)) * 8))
if err != nil {
status_code = WriteJsonRespHeader(w, http.StatusBadRequest)
je.Encode(JsonErrmsg{Text: "wrong peer id - " + peer_id})
goto oops
}
p = c.FindClientPeerConnById(ConnId(conn_nid), RouteId(route_nid), PeerId(peer_nid))
if p == nil {
status_code = WriteJsonRespHeader(w, http.StatusNotFound)
je.Encode(JsonErrmsg{Text: "non-existent connection/route/peer id - " + conn_id + "/" + route_id + "/" + peer_id})
je.Encode(JsonErrmsg{Text: err.Error()})
goto oops
}

View File

@ -46,6 +46,7 @@ type ClientConnConfig struct {
Routes []ClientRouteConfig
ServerSeedTmout time.Duration
ServerAuthority string // http2 :authority header
ClientToken string
}
type ClientConnConfigActive struct {
@ -944,6 +945,7 @@ func (cts *ClientConn) RunTask(wg *sync.WaitGroup) {
var c_seed Seed
var s_seed *Seed
var p *peer.Peer
var client_token string
var ok bool
var err error
var opts []grpc.DialOption
@ -1010,13 +1012,15 @@ start_over:
cts.psc = &GuardedPacketStreamClient{Hodu_PacketStreamClient: psc}
if cts.C.token != "" {
err = cts.psc.Send(MakeConnDescPacket(cts.C.token))
client_token = cts.cfg.ClientToken
if client_token == "" { client_token = cts.C.token }
if client_token != "" {
err = cts.psc.Send(MakeConnDescPacket(client_token))
if err != nil {
cts.C.log.Write(cts.Sid, LOG_ERROR, "Failed to send conn-desc(%s) to server[%d] %s - %s", cts.C.token, cts.cfg.Index, cts.cfg.ServerAddrs[cts.cfg.Index], err.Error())
cts.C.log.Write(cts.Sid, LOG_ERROR, "Failed to send conn-desc(%s) to server[%d] %s - %s", client_token, cts.cfg.Index, cts.cfg.ServerAddrs[cts.cfg.Index], err.Error())
goto reconnect_to_server
} else {
cts.C.log.Write(cts.Sid, LOG_DEBUG, "Sending conn-desc(%s) to server[%d] %s", cts.C.token, cts.cfg.Index, cts.cfg.ServerAddrs[cts.cfg.Index])
cts.C.log.Write(cts.Sid, LOG_DEBUG, "Sending conn-desc(%s) to server[%d] %s", client_token, cts.cfg.Index, cts.cfg.ServerAddrs[cts.cfg.Index])
}
}
@ -1332,10 +1336,10 @@ func (c *Client) wrap_http_handler(handler ClientHttpHandler) http.Handler {
time_taken = time.Now().Sub(start_time)
if status_code > 0 {
if err == nil {
c.log.Write(handler.Id(), LOG_INFO, "[%s] %s %s %d %.9f", req.RemoteAddr, req.Method, req.URL.String(), status_code, time_taken.Seconds())
} else {
if err != nil {
c.log.Write(handler.Id(), LOG_INFO, "[%s] %s %s %d %.9f - %s", req.RemoteAddr, req.Method, req.URL.String(), status_code, time_taken.Seconds(), err.Error())
} else {
c.log.Write(handler.Id(), LOG_INFO, "[%s] %s %s %d %.9f", req.RemoteAddr, req.Method, req.URL.String(), status_code, time_taken.Seconds())
}
}
})
@ -1570,20 +1574,6 @@ func (c *Client) FindClientRouteById(conn_id ConnId, route_id RouteId) *ClientRo
return cts.FindClientRouteById(route_id)
}
func (c *Client) FindClientConnByIdStr(conn_id string) (*ClientConn, error) {
var conn_nid uint64
var cts *ClientConn
var err error
conn_nid, err = strconv.ParseUint(conn_id, 10, int(unsafe.Sizeof(ConnId(0)) * 8))
if err != nil { return nil, fmt.Errorf("invalid connection id %s - %s", conn_id, err.Error()); }
cts = c.FindClientConnById(ConnId(conn_nid))
if cts == nil { return nil, fmt.Errorf("non-existent connection id %d", conn_nid) }
return cts, nil
}
func (c *Client) FindClientRouteByServerPeerSvcPortId(conn_id ConnId, port_id PortId) *ClientRoute {
var cts *ClientConn
var ok bool
@ -1623,6 +1613,64 @@ func (c *Client) FindClientPeerConnById(conn_id ConnId, route_id RouteId, peer_i
return r.FindClientPeerConnById(peer_id)
}
func (c *Client) FindClientConnByIdStr(conn_id string) (*ClientConn, error) {
var conn_nid uint64
var cts *ClientConn
var err error
conn_nid, err = strconv.ParseUint(conn_id, 10, int(unsafe.Sizeof(ConnId(0)) * 8))
if err != nil {
return nil, fmt.Errorf("invalid connection id %s - %s", conn_id, err.Error());
//cts = c.FindClientConnByToken(conn_id) // if not numeric, attempt to use it as a token
//if cts == nil { return nil, fmt.Errorf("non-existent connection token '%s'", conn_id) }
} else {
cts = c.FindClientConnById(ConnId(conn_nid))
if cts == nil { return nil, fmt.Errorf("non-existent connection id %d", conn_nid) }
}
return cts, nil
}
func (c *Client) FindClientRouteByIdStr(conn_id string, route_id string) (*ClientRoute, error) {
var r *ClientRoute
var conn_nid uint64
var route_nid uint64
var err error
conn_nid, err = strconv.ParseUint(conn_id, 10, int(unsafe.Sizeof(ConnId(0)) * 8))
if err != nil { return nil, fmt.Errorf("invalid connection id %s - %s", conn_id, err.Error()) }
route_nid, err = strconv.ParseUint(route_id, 10, int(unsafe.Sizeof(RouteId(0)) * 8))
if err != nil { return nil, fmt.Errorf("invalid route id %s - %s", route_id, err.Error()) }
r = c.FindClientRouteById(ConnId(conn_nid), RouteId(route_nid))
if r == nil { return nil, fmt.Errorf("route(%d,%d) not found", conn_nid, route_nid) }
return r, nil
}
func (c *Client) FindClientPeerConnByIdStr(conn_id string, route_id string, peer_id string) (*ClientPeerConn, error) {
var p *ClientPeerConn
var conn_nid uint64
var route_nid uint64
var peer_nid uint64
var err error
conn_nid, err = strconv.ParseUint(conn_id, 10, int(unsafe.Sizeof(ConnId(0)) * 8))
if err != nil { return nil, fmt.Errorf("invalid connection id %s - %s", conn_id, err.Error()) }
route_nid, err = strconv.ParseUint(route_id, 10, int(unsafe.Sizeof(RouteId(0)) * 8))
if err != nil { return nil, fmt.Errorf("invalid route id %s - %s", route_id, err.Error()) }
peer_nid, err = strconv.ParseUint(peer_id, 10, int(unsafe.Sizeof(PeerId(0)) * 8))
if err != nil { return nil, fmt.Errorf("invalid peer id %s - %s", peer_id, err.Error()) }
p = c.FindClientPeerConnById(ConnId(conn_nid), RouteId(route_nid), PeerId(peer_nid))
if p == nil { return nil, fmt.Errorf("peer(%d,%d,%d) not found", conn_nid, route_nid, peer_nid) }
return p, nil
}
func (c *Client) ReqStop() {
if c.stop_req.CompareAndSwap(false, true) {
var cts *ClientConn

View File

@ -202,7 +202,7 @@ func (ctl *server_ctl_server_conns) ServeHTTP(w http.ResponseWriter, req *http.R
Id: cts.Id,
ClientAddr: cts.RemoteAddr.String(),
ServerAddr: cts.LocalAddr.String(),
ClientToken: cts.Token,
ClientToken: cts.ClientToken,
Routes: jsp,
})
cts.route_mtx.Unlock()
@ -270,7 +270,7 @@ func (ctl *server_ctl_server_conns_id) ServeHTTP(w http.ResponseWriter, req *htt
Id: cts.Id,
ClientAddr: cts.RemoteAddr.String(),
ServerAddr: cts.LocalAddr.String(),
ClientToken: cts.Token,
ClientToken: cts.ClientToken,
Routes: jsp,
}
cts.route_mtx.Unlock()

View File

@ -34,7 +34,7 @@ const HS_ID_PXY string = "pxy"
const HS_ID_PXY_WS string = "pxy-ws"
type ServerConnMapByAddr = map[net.Addr]*ServerConn
type ServerConnMapByToken = map[string]*ServerConn
type ServerConnMapByClientToken = map[string]*ServerConn
type ServerConnMap = map[ConnId]*ServerConn
type ServerRouteMap = map[RouteId]*ServerRoute
type ServerPeerConnMap = map[PeerId]*ServerPeerConn
@ -102,7 +102,7 @@ type Server struct {
cts_mtx sync.Mutex
cts_map ServerConnMap
cts_map_by_addr ServerConnMapByAddr
cts_map_by_token ServerConnMapByToken
cts_map_by_token ServerConnMapByClientToken
cts_wg sync.WaitGroup
log Logger
@ -130,7 +130,7 @@ type ServerConn struct {
S *Server
Id ConnId
Sid string // for logging
Token string // provided by client
ClientToken string // provided by client
RemoteAddr net.Addr // client address that created this structure
LocalAddr net.Addr // local address that the client is connected to
@ -755,9 +755,9 @@ func (cts *ServerConn) receive_from_stream(wg *sync.WaitGroup) {
if x.Conn.Token == "" {
cts.S.log.Write(cts.Sid, LOG_ERROR, "Invalid conn_desc packet from %s - blank token", cts.RemoteAddr)
cts.ReqStop() // TODO: is this desirable to disconnect?
} else if x.Conn.Token != cts.Token {
} else if x.Conn.Token != cts.ClientToken {
_, err = strconv.ParseUint(x.Conn.Token, 10, int(unsafe.Sizeof(ConnId(0)) * 8))
if err == nil {
if err == nil { // this is not != nil. this is to check if the token is numeric
cts.S.log.Write(cts.Sid, LOG_ERROR, "Invalid conn_desc packet from %s - numeric token '%s'", cts.RemoteAddr, x.Conn.Token)
cts.ReqStop() // TODO: is this desirable to disconnect?
} else {
@ -769,8 +769,8 @@ func (cts *ServerConn) receive_from_stream(wg *sync.WaitGroup) {
cts.S.log.Write(cts.Sid, LOG_ERROR, "Invalid conn_desc packet from %s - duplicate token '%s'", cts.RemoteAddr, x.Conn.Token)
cts.ReqStop() // TODO: is this desirable to disconnect?
} else {
if cts.Token != "" { delete(cts.S.cts_map_by_token, cts.Token) }
cts.Token = x.Conn.Token
if cts.ClientToken != "" { delete(cts.S.cts_map_by_token, cts.ClientToken) }
cts.ClientToken = x.Conn.Token
cts.S.cts_map_by_token[x.Conn.Token] = cts
cts.S.cts_mtx.Unlock()
cts.S.log.Write(cts.Sid, LOG_INFO, "client(%d) %s - token set to '%s'", cts.Id, cts.RemoteAddr, x.Conn.Token)
@ -1079,10 +1079,10 @@ func (s *Server) wrap_http_handler(handler ServerHttpHandler) http.Handler {
time_taken = time.Now().Sub(start_time)
if status_code > 0 {
if err == nil {
s.log.Write(handler.Id(), LOG_INFO, "[%s] %s %s %d %.9f", req.RemoteAddr, req.Method, req.URL.String(), status_code, time_taken.Seconds())
} else {
if err != nil {
s.log.Write(handler.Id(), LOG_INFO, "[%s] %s %s %d %.9f - %s", req.RemoteAddr, req.Method, req.URL.String(), status_code, time_taken.Seconds(), err.Error())
} else {
s.log.Write(handler.Id(), LOG_INFO, "[%s] %s %s %d %.9f", req.RemoteAddr, req.Method, req.URL.String(), status_code, time_taken.Seconds())
}
}
})
@ -1128,7 +1128,7 @@ func NewServer(ctx context.Context, name string, logger Logger, cfg *ServerConfi
s.cts_next_id = 1
s.cts_map = make(ServerConnMap)
s.cts_map_by_addr = make(ServerConnMapByAddr)
s.cts_map_by_token = make(ServerConnMapByToken)
s.cts_map_by_token = make(ServerConnMapByClientToken)
s.svc_port_map = make(ServerSvcPortMap)
s.stop_chan = make(chan bool, 8)
s.stop_req.Store(false)
@ -1586,15 +1586,15 @@ func (s *Server) AddNewServerConn(remote_addr *net.Addr, local_addr *net.Addr, p
s.cts_mtx.Unlock()
return nil, fmt.Errorf("existing client address - %s", cts.RemoteAddr.String())
}
if cts.Token != "" {
if cts.ClientToken != "" {
// this check is not needed as Token is never set at this phase
// however leave statements here for completeness
_, ok = s.cts_map_by_token[cts.Token]
_, ok = s.cts_map_by_token[cts.ClientToken]
if ok {
s.cts_mtx.Unlock()
return nil, fmt.Errorf("existing client token - %s", cts.Token)
return nil, fmt.Errorf("existing client token - %s", cts.ClientToken)
}
s.cts_map_by_token[cts.Token] = &cts
s.cts_map_by_token[cts.ClientToken] = &cts
}
s.cts_map_by_addr[cts.RemoteAddr] = &cts
s.cts_map[cts.Id] = &cts
@ -1630,7 +1630,7 @@ func (s *Server) RemoveServerConn(cts *ServerConn) error {
delete(s.cts_map, cts.Id)
delete(s.cts_map_by_addr, cts.RemoteAddr)
if cts.Token != "" { delete(s.cts_map_by_token, cts.Token) }
if cts.ClientToken != "" { delete(s.cts_map_by_token, cts.ClientToken) }
s.stats.conns.Store(int64(len(s.cts_map)))
s.cts_mtx.Unlock()
@ -1651,7 +1651,7 @@ func (s *Server) RemoveServerConnByAddr(addr net.Addr) (*ServerConn, error) {
}
delete(s.cts_map, cts.Id)
delete(s.cts_map_by_addr, cts.RemoteAddr)
if cts.Token != "" { delete(s.cts_map_by_token, cts.Token) }
if cts.ClientToken != "" { delete(s.cts_map_by_token, cts.ClientToken) }
s.stats.conns.Store(int64(len(s.cts_map)))
s.cts_mtx.Unlock()
@ -1659,7 +1659,7 @@ func (s *Server) RemoveServerConnByAddr(addr net.Addr) (*ServerConn, error) {
return cts, nil
}
func (s *Server) RemoveServerConnByToken(token string) (*ServerConn, error) {
func (s *Server) RemoveServerConnByClientToken(token string) (*ServerConn, error) {
var cts *ServerConn
var ok bool
@ -1672,7 +1672,7 @@ func (s *Server) RemoveServerConnByToken(token string) (*ServerConn, error) {
}
delete(s.cts_map, cts.Id)
delete(s.cts_map_by_addr, cts.RemoteAddr)
delete(s.cts_map_by_token, cts.Token) // no Empty check becuase an empty token is never found in the map
delete(s.cts_map_by_token, cts.ClientToken) // no Empty check becuase an empty token is never found in the map
s.stats.conns.Store(int64(len(s.cts_map)))
s.cts_mtx.Unlock()
@ -1706,7 +1706,7 @@ func (s *Server) FindServerConnByAddr(addr net.Addr) *ServerConn {
return cts
}
func (s *Server) FindServerConnByToken(token string) *ServerConn {
func (s *Server) FindServerConnByClientToken(token string) *ServerConn {
var cts *ServerConn
var ok bool
@ -1842,8 +1842,8 @@ func (s *Server) FindServerConnByIdStr(conn_id string) (*ServerConn, error) {
conn_nid, err = strconv.ParseUint(conn_id, 10, int(unsafe.Sizeof(ConnId(0)) * 8))
if err != nil {
//return nil, fmt.Errorf("invalid connection id %s - %s", conn_id, err.Error()); }
cts = s.FindServerConnByToken(conn_id) // if not numeric, attempt to use it as a token
//return nil, fmt.Errorf("invalid connection id %s - %s", conn_id, err.Error());
cts = s.FindServerConnByClientToken(conn_id) // if not numeric, attempt to use it as a token
if cts == nil { return nil, fmt.Errorf("non-existent connection token '%s'", conn_id) }
} else {
cts = s.FindServerConnById(ConnId(conn_nid))