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 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 (c *Client) newConnect2LoalNetwork() error { if pConfig.currThread < pConfig.MaxThread { go Connect2Serv(pConfig.orwardServ, pConfig) } // 与本地局域网服务器g_localForwardHostAndPort 建立socket连接 c.rw.Lock() defer c.rw.Unlock() if c.localConn != nil { log.Warn("[%s], thread is busy. can not create new connect.", c) c.tellServBusy() return fmt.Errorf("[%s] thread is busy. can not create new connect.", c) } conn, err := net.Dial("tcp", g_localForwardHostAndPort) if err != nil { log.Error("[%s] Connect to[%s] err=%s", c, g_localForwardHostAndPort, err.Error()) c.tellServError(err) return err } go c.readForward(conn) c.localConn = &conn c.forwardData = make(chan []byte, Default_Channel_Size*4) go c.writerForward(conn) log.Info("new connection was create [%s]", conn.RemoteAddr()) return nil }
func bindConnection(conn net.Conn) error { // 与一个websocket 绑定一个连接 client, err := getFreeClient() if err != nil { return err } client.writerForward = conn.(io.WriteCloser) client.tellClientNewConnection() reader := conn.(io.Reader) p := make([]byte, 4096) for { n, err := reader.Read(p) if err != nil { if err != io.EOF { log.Error("Reading data from[%s] err=%s", conn.RemoteAddr(), err.Error()) } client.closeWriter() break } client.websocket.Write(p[:n], true) } log.Info("BindConnection Request finish.") return nil }
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 (this *Connect) Send(status int, value interface{}) error { if _, ok := value.(error); ok { log.Error("linuNum -> %d : %v", status, value) } this.Chan <- ReturnStr(this.Request, status, value) //this.Request = nil return nil }
func (ctrl *WebSocketControlFrame) Bytes() []byte { bytes, err := json.Marshal(ctrl) if err != nil { panic(err.Error()) log.Error("JSON format err=", err.Error()) return []byte("") } return bytes }
func ppLogin(ppToken string) string { if len(ppToken) != 32 { return "" } pp_id := 4335 app_key := "8dbbcdf221234073ccd75b1a277f7255" url := "http://passport_i.25pp.com:8080/account?tunnel-command=2852126760" m := md5.New() m.Write([]byte("sid=" + ppToken + app_key)) sign := hex.EncodeToString(m.Sum(nil)) postData := `{"data":{"sid":"%s"},"encrypt":"MD5","game":{"gameId":%d},"id":%d,"service":"account.verifySession","sign":"%s"}` postData = fmt.Sprintf(postData, ppToken, pp_id, time.Now().Unix(), sign) client := new(http.Client) resp, err := client.Post(url, "application/x-www-form-urlencoded", strings.NewReader(postData)) if err != nil { log.Error("PPLOGIN ERROR , line: %d", lineNum()) return "" } body, _ := ioutil.ReadAll(resp.Body) resp.Body.Close() var jsonData map[string]interface{} if json.Unmarshal(body, &jsonData) != nil { log.Error("PPLOGIN ERROR , line: %d", lineNum()) return "" } code := jsonData["state"].(map[string]interface{}) if int(code["code"].(float64)) != 1 { log.Error("PPLOGIN ERROR , line: %d", lineNum()) return "" } data := jsonData["data"].(map[string]interface{}) return data["accountId"].(string) }
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 Connect2Serv(forwardServ string, conf *Config) { if conf == nil { panic("config is nil.") } // global pConfig pConfig = conf pConfig.orwardServ = forwardServ var localServ, auth = conf.LocalHostServ, conf.WebsocketAuth setLocalForardHostAndPort(localServ) websockURI := ctrl.WEBSOCKET_CONNECT_URI log.Info("start TCP connect to[%s]", forwardServ) conn, err := net.Dial("tcp", forwardServ) if err != nil { log.Error("connect[%s] fail err=[%s]", forwardServ, err.Error()) return } var headers http.Header if auth != "" { headers = http.Header{} headers.Add("Authorization", fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte(auth)))) } log.Info("start websocket NewClient to[%s][%s]", forwardServ, websockURI) ws, _, err := websocket.NewClient(conn, &url.URL{Host: forwardServ, Path: websockURI}, headers) if err != nil { log.Error("Connect to[%s] err=%s", forwardServ, err.Error()) return } client := NewClient(ws) log.Info("Connect[%s] success at[%s], wait for server command.", forwardServ, client) pConfig.currThread++ client.waitForCommand() pConfig.currThread-- log.Info("client thread exist.") }
func login91(uin string, session string) error { appId := 100 appKey := "" sign := strconv.Itoa(appId) + "4" + uin + session + appKey m := md5.New() m.Write([]byte(sign)) sign = hex.EncodeToString(m.Sum(nil)) url := "http://service.sj.91.com/usercenter/ap.aspx?AppId=%d&Act=4&Uin=%s&SessionId=%s&Sign=" + sign url = fmt.Sprintf(url, appId, uin, session) client := new(http.Client) resp, err := client.Get(url) if err != nil { log.Error("91LOGIN ERROR , line: %d , %v", lineNum(), err) return err } body, _ := ioutil.ReadAll(resp.Body) resp.Body.Close() var jsonData map[string]string if err = json.Unmarshal(body, &jsonData); err != nil { log.Error("91LOGIN ERROR , line: %d , %v", lineNum(), err) return err } if jsonData["ErrorCode"] != "1" { err = fmt.Errorf("ErrorCode != 1") log.Error("91LOGIN ERROR , line: %d , %v", lineNum(), err) return err } return nil }
// 从客户端读取信息 func (this *Connect) PullFromClient() { for { defer func() { if err := recover(); err != nil { log.Critical("Panic occur. %v", err) this.Send(lineNum(), fmt.Sprintf("%v", err)) this.PullFromClient() } }() var content []byte err := websocket.Message.Receive(this.Conn, &content) if err != nil { log.Info("Websocket Error: %v", err) playerMap.Delete(this.Uid, this) return } beginTime := time.Now() log.Info(" Begin ") // parse proto message this.Request, err = ParseContent(content) if err != nil { log.Error("Parse client request error. %v", err) this.Send(lineNum(), err) continue } if this.Request.GetCmdId() != LOGIN { if !this.verify(this.Request.GetTokenStr()) { continue } } this.Function(this.Request.GetCmdId())() execTime := time.Now().Sub(beginTime) if execTime.Seconds() > 0.1 { // slow log log.Warn("Slow Exec , time is %v second", execTime.Seconds()) } else { log.Info("time is %v second", execTime.Seconds()) } } }
func (c *Client) readForward(reader io.Reader) { // 从本地局域网连接中读取到数据,通过websocket的Binary帧方式发给服务器 p := make([]byte, Default_Buffer_Size) var err error for { n, err := reader.Read(p) if err != nil { break } c.Write(p[:n]) } if err != nil && err != io.EOF { log.Error("Write to Local-network err=%s", err.Error()) } c.closeLoalNetworkConnection(true) log.Info("end reader forward.") }
func (c *Client) writerForward(writer io.Writer) { buff := make([]byte, Default_Buffer_Size) var err error for { buff = <-c.forwardData _, err = writer.Write(buff) if err != nil { break } } if err != nil && err != io.EOF { log.Error("Write to Local-network err=%s", err.Error()) } c.closeLoalNetworkConnection(false) log.Info("end writer forward.") }
func otherLogin(platId int, otherId, session, sign, otherData string) (string, bool) { if platId == 0 { return otherId, true } Lua, err := lua.NewLua(fmt.Sprintf("lua/plat_%d.lua", platId)) if err != nil { log.Error("LUA ERROR : login.go line - 60") return "0", false } Lua.L.GetGlobal("isLogin") Lua.L.DoString(fmt.Sprintf("uid, isLogin = isLogin('%s', '%s', '%s', '%s')", otherId, session, sign, otherData)) uid := Lua.GetString("uid") isLogin := Lua.GetBool("isLogin") Lua.Close() return uid, isLogin }
func listenWebsocketServ(hostAndPort string, websocketURI, contorlURI string) { // TODO:连接认证 http.HandleFunc(websocketURI, WebsocketHandler) http.HandleFunc(contorlURI, httpAdminHandler) http.HandleFunc("/api/", httpApiHandler) log.Info("Websocket Listen in TCP[%s]", hostAndPort) svr := &http.Server{ Addr: hostAndPort, Handler: nil, ReadTimeout: 0 * time.Second, WriteTimeout: 0 * time.Second, MaxHeaderBytes: 1 << 20, // 1M } err := svr.ListenAndServe() if err != nil { log.Error("ListenAndServe[%v], err=[%v]", hostAndPort, err.Error()) } log.Info("ListenWebsocketServ exit.") }
func (c *Client) handlerControlFrame(bFrame []byte) (err error) { msg := ctrl.WebSocketControlFrame{} if err = json.Unmarshal(bFrame, &msg); err != nil { log.Error("Recve a Text-Frame not JSON format. err=%v, frame=%v", err.Error(), string(bFrame)) return err } log.Info("TCP[%v] Get Frame T[%v], Content=%v, index=%v, ", c, msg.TypeStr(), msg.Content, msg.Index) switch msg.Type { case ctrl.Msg_New_Connection: c.newConnect2LoalNetwork() case ctrl.Msg_Request_Finish: c.closeLocalConnect() case ctrl.Msg_Get_Config: err = c.telServConfig() case ctrl.Msg_Set_Config: pConfig.LocalHostServ = msg.Content err = c.telServConfig() default: log.Warn("no handler Msg T[%s]", msg.TypeStr()) } return err }