fixed a bug of not unlocking a mutex when checking port uniqueness in adding a route listener

This commit is contained in:
hyung-hwan 2025-01-14 16:47:14 +09:00
parent ea56287eb4
commit a52926d017
2 changed files with 24 additions and 23 deletions

View File

@ -51,12 +51,14 @@ type server_proxy_http_wpx struct {
// this is minimal information for wpx to work // this is minimal information for wpx to work
type ServerRouteProxyInfo struct { type ServerRouteProxyInfo struct {
// command fields with ServerRoute
SvcOption RouteOption SvcOption RouteOption
PtcAddr string PtcAddr string
PtcName string PtcName string
SvcAddr *net.TCPAddr SvcAddr *net.TCPAddr
SvcPermNet netip.Prefix SvcPermNet netip.Prefix
// extra fields added after proessing
PathPrefix string PathPrefix string
ConnId string ConnId string
RouteId string RouteId string
@ -192,7 +194,7 @@ func prevent_follow_redirect (req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse return http.ErrUseLastResponse
} }
func (pxy *server_proxy_http_main) get_route(req *http.Request, in_wpx_mode bool) (*ServerRouteProxyInfo, error) { func (pxy *server_proxy_http_main) get_route_proxy_info(req *http.Request, in_wpx_mode bool) (*ServerRouteProxyInfo, error) {
var conn_id string var conn_id string
var route_id string var route_id string
var r *ServerRoute var r *ServerRoute
@ -202,7 +204,7 @@ func (pxy *server_proxy_http_main) get_route(req *http.Request, in_wpx_mode bool
if in_wpx_mode { // for wpx if in_wpx_mode { // for wpx
conn_id = req.PathValue("port_id") conn_id = req.PathValue("port_id")
route_id = pxy.prefix route_id = pxy.prefix // this is PORT_ID_MARKER
} else { } else {
conn_id = req.PathValue("conn_id") conn_id = req.PathValue("conn_id")
route_id = req.PathValue("route_id") route_id = req.PathValue("route_id")
@ -348,7 +350,7 @@ func (pxy *server_proxy_http_main) ServeHTTP(w http.ResponseWriter, req *http.Re
s = pxy.s s = pxy.s
in_wpx_mode = (pxy.prefix == PORT_ID_MARKER) in_wpx_mode = (pxy.prefix == PORT_ID_MARKER)
pi, err = pxy.get_route(req, in_wpx_mode) pi, err = pxy.get_route_proxy_info(req, in_wpx_mode)
if err != nil { if err != nil {
status_code = write_empty_resp_header(w, http.StatusNotFound) status_code = write_empty_resp_header(w, http.StatusNotFound)
goto oops goto oops

View File

@ -188,9 +188,7 @@ func NewServerRoute(cts *ServerConn, id RouteId, option RouteOption, ptc_addr st
} }
l, svcaddr, err = cts.make_route_listener(id, option, svc_requested_addr) l, svcaddr, err = cts.make_route_listener(id, option, svc_requested_addr)
if err != nil { if err != nil { return nil, err }
return nil, err
}
if svc_permitted_net == "" { if svc_permitted_net == "" {
if svcaddr.IP.To4() != nil { if svcaddr.IP.To4() != nil {
@ -363,34 +361,36 @@ func (cts *ServerConn) make_route_listener(id RouteId, option RouteOption, svc_r
} }
if option & RouteOption(ROUTE_OPTION_TCP) != 0 { if option & RouteOption(ROUTE_OPTION_TCP) != 0 {
nw = "tcp" nw = "tcp"
if svcaddr == nil { if svcaddr == nil {
svcaddr = &net.TCPAddr{Port: 0} // port 0 for automatic assignment. // port 0 for automatic assignment.
} svcaddr = &net.TCPAddr{Port: 0}
}
} else if option & RouteOption(ROUTE_OPTION_TCP4) != 0 { } else if option & RouteOption(ROUTE_OPTION_TCP4) != 0 {
nw = "tcp4" nw = "tcp4"
if svcaddr == nil { if svcaddr == nil {
svcaddr = &net.TCPAddr{IP: net.IPv4zero, Port: 0} // port 0 for automatic assignment. svcaddr = &net.TCPAddr{IP: net.IPv4zero, Port: 0}
} }
} else if option & RouteOption(ROUTE_OPTION_TCP6) != 0 { } else if option & RouteOption(ROUTE_OPTION_TCP6) != 0 {
nw = "tcp6" nw = "tcp6"
if svcaddr == nil { if svcaddr == nil {
svcaddr = &net.TCPAddr{IP: net.IPv6zero, Port: 0} // port 0 for automatic assignment. svcaddr = &net.TCPAddr{IP: net.IPv6zero, Port: 0}
} }
} else { } else {
return nil, nil, fmt.Errorf("invalid route option value %d(%s)", option, option.string()) return nil, nil, fmt.Errorf("invalid route option value %d(%s)", option, option.string())
} }
l, err = net.ListenTCP(nw, svcaddr) // make the binding address configurable. support multiple binding addresses??? l, err = net.ListenTCP(nw, svcaddr) // make the binding address configurable. support multiple binding addresses???
if err != nil { if err != nil { return nil, nil, err }
return nil, nil, err
}
svcaddr = l.Addr().(*net.TCPAddr) svcaddr = l.Addr().(*net.TCPAddr)
// uniqueness by port id can be checked after listener creation,
// especially when automatic assignment is requested.
cts.svr.svc_port_mtx.Lock() cts.svr.svc_port_mtx.Lock()
prev_cri, ok = cts.svr.svc_port_map[PortId(svcaddr.Port)] prev_cri, ok = cts.svr.svc_port_map[PortId(svcaddr.Port)]
if ok { if ok {
cts.svr.svc_port_mtx.Unlock()
cts.svr.log.Write(cts.sid, LOG_ERROR, cts.svr.log.Write(cts.sid, LOG_ERROR,
"Route(%d,%d) on %s not unique by port number - existing route(%d,%d)", "Route(%d,%d) on %s not unique by port number - existing route(%d,%d)",
cts.Id, id, prev_cri.conn_id, prev_cri.route_id, svcaddr.String()) cts.Id, id, prev_cri.conn_id, prev_cri.route_id, svcaddr.String())
@ -1134,7 +1134,6 @@ func NewServer(ctx context.Context, logger Logger, ctl_addrs []string, rpc_addrs
Handler: s.wpx_mux, Handler: s.wpx_mux,
TLSConfig: s.wpxtlscfg, TLSConfig: s.wpxtlscfg,
ErrorLog: hs_log, ErrorLog: hs_log,
// TODO: more settings
} }
} }
// --------------------------------------------------------- // ---------------------------------------------------------