Пример #1
0
func (sc *Client) Run(index int, specPipe string) {
	var pipe net.Conn
	if index >= 0 {
		pipe = sc.pipes[index]
	} else {
		pipe = sc.specPipes[specPipe]
	}
	if pipe == nil {
		return
	}
	go func() {
		callback := func(conn net.Conn, sessionId, action, content string) {
			if sc != nil {
				sc.OnTunnelRecv(conn, sessionId, action, content)
			}
		}
		common.Read(pipe, callback)
		log.Println("client end read", index)
		if index >= 0 {
			delete(sc.pipes, index)
			if clientType == 1 {
				if len(sc.pipes) == 0 {
					if remoteConn != nil {
						remoteConn.Close()
					}
				}
			}
		} else {
			delete(sc.specPipes, specPipe)
		}
	}()
}
Пример #2
0
func handleClient(conn net.Conn) {
	common.Conn2ClientInfo[conn] = &common.ClientInfo{Conn: conn, ClientMap: make(map[net.Conn]*common.Session), Id2Session: make(map[string]*common.Session), IsServer: false, Quit: make(chan bool), ResponseTime: time.Now().Unix()}
	log.Println("client linked success", conn.RemoteAddr().String())
	common.Conn2ClientInfo[conn].Loop()
	common.Read(conn, handleResponse)
	client, bHave := common.Conn2ClientInfo[conn]
	if bHave {
		close(client.Quit)
		if client.IsServer {
			for conn, session := range client.ClientMap {
				conn.Close()
				common.RmId(client.ServerName, session.Id)
			}
			delete(common.ServerName2Conn, client.ServerName)
			log.Println("unregister service Name", client.ServerName)
			if bUseDB {
				user, _ := auth.GetUser(client.UserName)
				if user != nil {
					user.OnLogout()
				}
			}
		} else {
			common.GetServerInfoByConn(conn, func(server *common.ClientInfo) {
				id := server.DelClient(conn)
				log.Println("send quit")
				common.Write(server.Conn, id, "clientquit", "")
			}, func() {})
		}
		delete(common.Conn2ClientInfo, conn)
	}
	conn.Close()
	log.Println("client disconnected", conn.RemoteAddr().String())
}
Пример #3
0
func main() {
	flag.Parse()
	checkDns = make(chan *dnsQueryReq)
	checkDnsRes = make(chan *dnsQueryBack)
	go dnsLoop()
	if *bShowVersion {
		fmt.Printf("%.2f\n", common.Version)
		return
	}
	if !*bVerbose {
		log.SetOutput(ioutil.Discard)
	}
	if *dataShards < 0 || *dataShards >= 128 {
		println("-ds should in [0-127]")
		return
	}
	if *parityShards < 0 || *parityShards >= 128 {
		println("-ds should in [0-127]")
		return
	}
	if *serveName == "" && *linkName == "" {
		println("you must assign reg or link")
		return
	}
	if *serveName != "" && *linkName != "" {
		println("you must assign reg or link, not both of them")
		return
	}
	if *localAddr == "" {
		println("you must assign the local addr")
		return
	}
	if *serveName != "" {
		clientType = 0
	} else {
		clientType = 1
	}
	if *bEncrypt {
		if clientType != 1 {
			println("only link size need encrypt")
			return
		}
	}
	go func() {
		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt, syscall.SIGTERM)
		n := 0
		for {
			<-c
			log.Println("received signal,shutdown")
			bForceQuit = true
			if remoteConn != nil {
				remoteConn.Close()
			}
			n++
			if n > 5 {
				log.Println("force shutdown")
				os.Exit(-1)
			}
		}
	}()

	loop := func() bool {
		if bForceQuit {
			return true
		}
		g_ClientMap = make(map[string]*Client)
		g_ClientMapKey = make(map[string]*cipher.Block)
		g_Id2UDPSession = make(map[string]*UDPMakeSession)
		//var err error
		if *bUseSSL {
			_remoteConn, err := tls.Dial("tcp", *serverAddr, &tls.Config{InsecureSkipVerify: true})
			if err != nil {
				println("connect remote err:" + err.Error())
				return false
			}
			remoteConn = net.Conn(_remoteConn)
		} else {
			_remoteConn, err := net.DialTimeout("tcp", *serverAddr, 10*time.Second)
			if err != nil {
				println("connect remote err:" + err.Error())
				return false
			}
			remoteConn = _remoteConn
		}
		println("connect to server succeed")
		go connect()
		q := make(chan bool)
		go func() {
			c := time.NewTicker(time.Second * 10)
		out:
			for {
				select {
				case <-c.C:
					if remoteConn != nil {
						common.Write(remoteConn, "-1", "ping", "")
					}
				case <-q:
					break out
				}
			}
			c.Stop()
		}()

		common.Read(remoteConn, handleResponse)
		q <- true
		for clientId, client := range g_ClientMap {
			log.Println("client shutdown", clientId)
			client.Quit()
		}

		for _, session := range g_Id2UDPSession {
			if session.engine != nil {
				session.engine.Fail()
			}
		}
		if remoteConn != nil {
			remoteConn.Close()
		}
		if bForceQuit {
			return true
		}
		return false
	}
	if clientType == 0 {
		for {
			if loop() {
				break
			}
			time.Sleep(10 * time.Second)
		}
	} else {
		loop()
	}
	log.Println("service shutdown")
}