func (c *wsClient) handlerControlMessage(bFrame []byte) error { msg := ctrl.WebSocketControlFrame{} if err := json.Unmarshal(bFrame, &msg); err != nil { log.Warn("Recve a Text-Frame not JSON format. err=%v, frame=%v", err.Error(), string(bFrame)) return err } log.Debug("TCP[%v] Get Frame T[%v], Content=%v, index=%v, ", c, msg.TypeStr(), msg.Content, msg.Index) switch msg.Type { case ctrl.Msg_Request_Finish: c.closeWriter() case ctrl.Msg_Client_Busy: c.writerForward.Write([]byte("current client was busy, pls try anthor.")) c.closeWriter() case ctrl.Msg_Sys_Err: c.writerForward.Write([]byte(msg.Content)) c.closeWriter() case ctrl.Msg_Get_Config: log.Info("Get the Client- side local network server config[%s]", msg.Content) pConfig.client_conf_forward_host = msg.Content default: log.Warn("no handler Msg T[%s]", msg.TypeStr()) } return nil }
func WebsocketHandler(w http.ResponseWriter, r *http.Request) { log.Info("WebsocketHandler:%s %s %s", r.RemoteAddr, r.Method, r.URL.Path) if !authOK(r) { log.Warn("auth fail....") noAuthResponse(w) return } var conn *websocket.Conn conn, err := websocket.Upgrade(w, r, http.Header{}) if err != nil { log.Error(err.Error()) return } conn.SetReadDeadline(time.Time{}) conn.SetWriteDeadline(time.Time{}) var client = newWebsocketClient(conn, r) if pConfig.client_conf_forward_host == "" { log.Info("pConfig.client_conf_forward_host is empty. tell Client Need the Config.") client.tellClientNeedConfig() } log.Info("Put[%s] into the global Connect pool.", client) client.waitForFrameLoop() websocketClose(r) log.Debug("WebsocketHandler:%s closed.", r.RemoteAddr) }
func ListenIPForwardAndWebsocketServ(forwardHostAndPort, websocketHostAndPort string, conf *Config) { if conf == nil { panic("config is nil.") } pConfig = conf if pConfig.Auth != "" { pConfig.Auth = fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte(pConfig.Auth))) } go listenWebsocketServ(websocketHostAndPort, ctrl.WEBSOCKET_CONNECT_URI, WEBSOCKET_CONTORL_URI) l, err := net.Listen("tcp", forwardHostAndPort) if err != nil { log.Error(err.Error()) } defer l.Close() log.Debug("IP Forward Listening TCP[%s]", forwardHostAndPort) for { conn, err := l.Accept() if err != nil { log.Error("IP-Forward Accept err=%s", err.Error()) continue } // handle socket data recv and send go ipforward(conn) } log.Info("ListenAndIPForwardServ exit.") }
func (client *wsClient) waitForFrameLoop() { for { frameType, bFrame, err := client.websocket.Read() log.Debug("TCP[%s] recv WebSocket Frame typ=[%v] size=[%d], crc32=[%d]", client, frameTypStr(frameType), len(bFrame), crc32.ChecksumIEEE(bFrame)) if err != nil { if err != io.ErrUnexpectedEOF { log.Error("TCP[%s] close Unexpected err=%v", client, err.Error()) } else { log.Debug("TCP[%s] close the socket. EOF.", client) } client.closeWriter() return } switch frameType { case websocket.TextMessage: client.handlerControlMessage(bFrame) case websocket.CloseMessage: log.Info("TCP[%s] close Frame revced. end wait Frame loop", client) client.closeWriter() return case websocket.BinaryMessage: log.Info("TCP[%s] resv-binary: %v", client, len(bFrame)) if client.writerForward == nil { log.Warn("client.writerForward is nil.") continue } _, err := client.writerForward.Write(bFrame) if err != nil { if err != io.EOF { log.Error(err.Error()) } client.tellClientRequestFinish() client.closeWriter() } case websocket.PingMessage, websocket.PongMessage: // IE-11 会无端端发一个pong上来 client.websocket.Pong(bFrame) default: log.Warn("TODO: revce frame-type=%v. can not handler. content=%v", frameTypStr(frameType), string(bFrame)) } } }
func (client *Client) waitForCommand() { for { frameType, bFrame, err := client.webSocket.Read() log.Debug("TCP[%s] recv WebSocket Frame typ=[%v] size=[%d], crc32=[%d]", client, frameTypStr(frameType), len(bFrame), crc32.ChecksumIEEE(bFrame)) if err != nil { if err != io.ErrUnexpectedEOF { log.Error("TCP[%s] close Unexpected err=%v", client, err.Error()) } else { log.Debug("TCP[%s] close the socket. EOF.", client) } client.closeLocalConnect() return } switch frameType { case websocket.CloseMessage: log.Info("TCP[%s] close Frame revced. end wait Frame loop", client) client.closeLocalConnect() return case websocket.TextMessage: err := client.handlerControlFrame(bFrame) if err != nil { log.Error("handlerControlFrame ret[%s]", err.Error()) } case websocket.BinaryMessage: log.Info("put Binary-Data to chan-len[%d]", len(client.forwardData)) select { case client.forwardData <- bFrame: log.Info("put frame to client.forwardData len[%d] end", len(client.forwardData)) default: log.Warn("[%s] is busy", client) client.tellServBusy() } case websocket.PingMessage, websocket.PongMessage: // IE-11 会无端端发一个pong上来 client.webSocket.Pong(bFrame) default: log.Warn("TODO: revce frame-type=%v. can not handler. content=%v", frameTypStr(frameType), string(bFrame)) } } }
func ipforward(c net.Conn) { //只支持 TCP 协议的 Forward,如http,ssh log.Debug("new connect [%s]", c.RemoteAddr()) defer c.Close() err := bindConnection(c) if err != nil { c.Write([]byte(err.Error())) //c maybe closed. log.Error("Forward PutConnection err=%s", err.Error()) } }
func authOK(req *http.Request) bool { if pConfig == nil && pConfig.Auth == "" { log.Info("did not need auth.") return true } var auth = req.Header.Get("Authorization") log.Debug("reuquest Auth->[%s]", auth) return auth == pConfig.Auth }