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)
}
Example #2
0
func main() {
	flag.Parse()
	log.Info("start app, Read From[%s], forward data To[%s], auth[%s] log-level[%s].",
		_LocalNetworkHost, _ForwardServer, _AuthUserPassword, _LogLevel)

	log.SetLevelByName(_LogLevel)

	if _ForwardTHread < MIN_THREAD {
		_ForwardTHread = MIN_THREAD
	}

	conf := &cli.Config{
		LocalHostServ: _LocalNetworkHost,
		WebsocketAuth: _AuthUserPassword,
		MaxThread:     _ForwardTHread,
	}
	const (
		default_sleep_time = 10 * time.Second
	)
	for {
		cli.Connect2Serv(_ForwardServer, conf)
		if stop {
			break
		} else {
			log.Info("Connect2Serv fail, wait[%s]Second.", default_sleep_time)
			time.Sleep(default_sleep_time)
		}
	}
	log.Info("------------------- main end ------------------------")
}
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 (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
}
Example #5
0
// URI: /api/
func httpApiHandler(w http.ResponseWriter, r *http.Request) {
	log.Info("api Handler: %s %s %s", r.Method, r.URL.RequestURI(), r.RemoteAddr, r.FormValue("svr"))

	if !authOK(r) {
		noAuthResponse(w)
		return
	}
	var status = 200
	var resp string

	svr := r.FormValue("svr")
	if svr != "" && svr != pConfig.client_conf_forward_host {
		cli, err := getFreeClient()
		if cli == nil {
			resp = err.Error()
		} else {
			err := cli.tellClientSetConfig(svr)
			if err != nil {
				resp = err.Error()
			} else {
				resp = fmt.Sprintf("Set [%s] OK", svr)
			}
		}
	}

	setSTDheader(w)
	w.WriteHeader(status)
	io.WriteString(w, resp)
}
Example #6
0
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.")
}
Example #7
0
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
}
Example #8
0
// 从客户端读取信息
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 (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))
		}
	}
}
Example #10
0
func init() {
	rand.Seed(time.Now().UnixNano())
	gameToken = token.NewToken(token.NewAdapter())
	playerMap = new(PlayerMap)
	playerMap.Lock = new(sync.RWMutex)
	playerMap.Map = make(map[int64]*Connect)
	request_log_map = make(map[int32]string)
	CountOnline()
	log.Info("Program Run !")
}
Example #11
0
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))
		}
	}
}
Example #12
0
func (this *Connect) pushToClient() {
	go func() {
		for s := range this.Chan {
			if _, err := this.Conn.Write(s); err != nil {
				log.Warn("Can't send msg. %v", err)
			} else {
				log.Info("Send Success")
			}
		}
	}()
}
Example #13
0
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
}
Example #14
0
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.")
}
Example #15
0
func main() {
	flag.Parse()

	log.Info("app start forward[%s] websocket[%s] auth[%s] log-level[%s], ",
		_ForwardListtion, _Websocketlisten, _AuthUserPassword, _LogLevel)

	log.SetLevelByName(_LogLevel)

	var conf = &svr.Config{Auth: _AuthUserPassword}

	svr.ListenIPForwardAndWebsocketServ(_ForwardListtion, _Websocketlisten, conf)
}
Example #16
0
// URI: /admin/
func httpAdminHandler(w http.ResponseWriter, r *http.Request) {

	log.Info("admin Handler: %s %s %s", r.Method, r.URL.RequestURI(), r.RemoteAddr)

	if !authOK(r) {
		noAuthResponse(w)
		return
	}

	setSTDheader(w)
	resp := fmt.Sprintf(control_html, pConfig.client_conf_forward_host)
	io.WriteString(w, resp)
}
Example #17
0
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.")
}
Example #18
0
func (c *Client) closeLoalNetworkConnection(isReader bool) {
	c.rw.Lock()
	defer c.rw.Unlock()
	if c.localConn == nil {
		return
	}
	if isReader {
		// 如果readForward函数先结束,writerForward 中的buff = <- c.forwardData会一直阻塞
		// 此处发一个字节作信号,使 writerForward 退出
		c.forwardData <- []byte("")
	}

	(*c.localConn).Close()
	c.tellServRequestFinish()
	log.Info("connection was close[%s]", (*c.localConn).RemoteAddr())
	c.localConn = nil
	close(c.forwardData)
}
Example #19
0
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.")
}
Example #20
0
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.")
}
Example #21
0
func (this *Connect) verify(token string) bool {

	if token == "" {
		this.Send(2, nil)
		return false
	}
	uid, _ := gameToken.GetUid(token)
	if uid == 0 {
		this.Send(2, nil)
		return false
	}
	if this.Role == nil {
		this.Uid = uid
		Role, err := models.Role.Role(uid)
		if err == sql.ErrNoRows {
			if Role, err = models.Role.NewRole(uid); err != nil {
				// 插入失败
				return false
			}
		} else if err != nil {
			this.Send(lineNum(), err)
			return false
		}
		this.Role = Role
		playerMap.Set(uid, this)

	} else if this.Role.Uid != uid {
		this.Send(2, nil)
		return false
	} else {
		this.Role.UpdateDate()
	}

	log.Info("Exec -> %d (uid:%d)", this.Request.GetCmdId(), this.Uid)
	models.InsertRequestLog(this.Uid, this.Request.GetCmdId())
	return true
}
Example #22
0
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
}
Example #23
0
func (this *Connect) Login() error {

	request := &protodata.LoginRequest{}
	if err := Unmarshal(this.Request.GetSerializedString(), request); err != nil {
		return this.Send(lineNum(), err)
	}

	platId := int(request.GetPlatId())
	username := request.GetUsername()
	password := request.GetPassword()
	otherId := request.GetOtherId()
	otherData := request.GetOtherData()
	session := request.GetOtherSession()
	sign := request.GetOtherSign()

	var user *models.UserData

	if platId == 2 { // PP助手
		otherId = ppLogin(session)
		if otherId == "" {
			return this.Send(lineNum(), fmt.Errorf("PP助手验证错误"))
		}
	} else {
		//else if platId == 4 { // 91助手
		//	if err := login91(otherId, session); err != nil {
		//		return this.Send(lineNum(), err)
		//	}
		//} else {
		var b bool
		otherId, b = otherLogin(platId, otherId, session, sign, otherData)
		if !b {
			return this.Send(lineNum(), fmt.Errorf("第三方验证错误"))
		}
	}

	user = models.User.GetUserByOtherId(otherId, platId)
	if user == nil {

		if platId == 0 {
			m := md5.New()
			m.Write([]byte(password))
			password = hex.EncodeToString(m.Sum(nil))
		}

		user = new(models.UserData)
		user.UserName = username
		user.Password = password
		user.OtherId = otherId
		user.Ip = request.GetIp()
		user.Imei = request.GetImei()
		user.PlatId = platId
		if err := user.Insert(); err != nil {
			return this.Send(lineNum(), err)
		}
	} else if platId == 0 {

		m := md5.New()
		m.Write([]byte(password))
		password = hex.EncodeToString(m.Sum(nil))
		if user.Password != password {
			return this.Send(lineNum(), fmt.Errorf("密码错误"))
		}
	}

	token, err := gameToken.AddToken(user.Uid)
	if err != nil {
		return this.Send(lineNum(), err)
	}

	log.Info("Exec -> login (uid:%d)", user.Uid)

	this.Uid = user.Uid
	if Role, err := models.Role.Role(user.Uid); err == nil {
		this.Role = Role
	}
	playerMap.Set(user.Uid, this)

	response := &protodata.LoginResponse{TokenStr: proto.String(token)}
	return this.Send(StatusOK, response)
}