I am having trouble closing a listener so that I can reopen it on the same port. I am writing a proxy server that is hot-configurable - i.e what it does (redirects/blocks etc) can be adjusted on the fly. The proxy runs in a go routine. The problem I am having is when I reconfigure the listener and proxy the listener is still using that port from the previous configuration. (FYI listener is a global pointer) I'm trying something like:
to kill the listener:
func KillProxy() {
if listener != nil {
log.Println(" *** TRYING TO STOP THE PROXY SERVER")
(*listener).Close()
listener = nil
}
}
before reconfiguring it like:
log.Println("listener (S1): ", listener)
if listener == nil {
// Start the listener to listen on the connection.
l, err := net.Listen(CONN_TYPE, CONN_HOST + ":" + CONN_PORT)
if err != nil {
log.Println("error here: ", err)
}
listener = &l //set it as a pointer to the newly created listener
}
log.Println("listener (S2): ", listener)
however that doesnt seem to work - I get the error:
listener (S1):
error here: listen tcp 0.0.0.0:8080: bind: address already in use
listener (S2): 0xc2080015e0
and then a massive stack trace that summizes to:
panic: runtime error: invalid memory address or nil pointer dereference
EDIT IN RESPONSE TO JIM:
Interesting re pointers. OK. I am not handling waiting for the socket to close, Im not sure how that should be done. The proxy library I am using is this one: https://github.com/abourget/goproxy. The order things happen is:
KillProxy()
refreshProxy()
refreshProxy holds the code posted above that tries to repurpose the listener. The last thing that happens in refreshProxy()
is:
go http.Serve(*listener, proxy)
So if I revert to listener being a global variable, not a pointer I can make KillProxy():
func KillProxy() {
if listener != nil {
listener.Close()
listener = nil
}
}
and then setup the listener again as
listener, err := net.Listen(CONN_TYPE, CONN_HOST + ":" + CONN_PORT)
if err != nil {
log.Println("error here: ", err)
}
However I don't know how to wait and check whether the socket has closed before trying to re create the listener object?
Ok this is far from perfect, but the only way I found of not having it error out on me was to artifically put a delay in my code so the socket had time to close. This isn't great as it means the proxy is down for 2 seconds while the socket closes, but at least it doesnt error out. If someone has a better solution I would like to hear it