Example #1
0
func main() {
	log.SetOutput(os.Stdout)

	var cmdConfig ss.Config
	var printVer bool
	var core int

	flag.BoolVar(&printVer, "version", false, "print version")
	flag.StringVar(&configFile, "c", "config.json", "specify config file")
	flag.StringVar(&cmdConfig.Password, "k", "", "password")
	flag.IntVar(&cmdConfig.ServerPort, "p", 0, "server port")
	flag.IntVar(&cmdConfig.Timeout, "t", 300, "timeout in seconds")
	flag.StringVar(&cmdConfig.Method, "m", "", "encryption method, default: aes-256-cfb")
	flag.IntVar(&core, "core", 0, "maximum number of CPU cores to use, default is determinied by Go runtime")
	flag.BoolVar((*bool)(&debug), "d", false, "print debug message")

	flag.Parse()

	if printVer {
		ss.PrintVersion()
		os.Exit(0)
	}

	ss.SetDebug(debug)

	if strings.HasSuffix(cmdConfig.Method, "-auth") {
		cmdConfig.Method = cmdConfig.Method[:len(cmdConfig.Method)-5]
		cmdConfig.Auth = true
	}

	var err error
	config, err = ss.ParseConfig(configFile)
	if err != nil {
		if !os.IsNotExist(err) {
			fmt.Fprintf(os.Stderr, "error reading %s: %v\n", configFile, err)
			os.Exit(1)
		}
		config = &cmdConfig
	} else {
		ss.UpdateConfig(config, &cmdConfig)
	}
	if config.Method == "" {
		config.Method = "aes-256-cfb"
	}
	if err = ss.CheckCipherMethod(config.Method); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	if err = unifyPortPassword(config); err != nil {
		os.Exit(1)
	}
	if core > 0 {
		runtime.GOMAXPROCS(core)
	}
	for port, password := range config.PortPassword {
		go run(port, password, config.Auth)
	}

	waitSignal()
}
Example #2
0
func main() {
	log.SetOutput(os.Stdout)

	var cmdConfig ss.Config
	var printVer bool
	var core int

	flag.BoolVar(&printVer, "version", false, "print version")
	flag.StringVar(&configFile, "c", "config.json", "specify config file")
	flag.StringVar(&cmdConfig.Password, "k", "", "password")
	flag.IntVar(&cmdConfig.ServerPort, "p", 0, "server port")
	flag.IntVar(&cmdConfig.Timeout, "t", 60, "connection timeout (in seconds)")
	flag.StringVar(&cmdConfig.Method, "m", "", "encryption method, use empty string or rc4")
	flag.IntVar(&core, "core", 0, "maximum number of CPU cores to use, default is determinied by Go runtime")
	flag.BoolVar((*bool)(&debug), "d", false, "print debug message")

	flag.Parse()

	if printVer {
		ss.PrintVersion()
		os.Exit(0)
	}

	ss.SetDebug(debug)

	var err error
	config, err = ss.ParseConfig(configFile)
	if err != nil {
		if !os.IsNotExist(err) {
			fmt.Fprintf(os.Stderr, "error reading %s: %v\n", configFile, err)
			os.Exit(1)
		}
		config = &cmdConfig
	} else {
		ss.UpdateConfig(config, &cmdConfig)
	}
	if err = unifyPortPassword(config); err != nil {
		os.Exit(1)
	}
	if err = ss.SetDefaultCipher(config.Method); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	if core > 0 {
		runtime.GOMAXPROCS(core)
	}
	for port, password := range config.PortPassword {
		go run(port, password)
	}

	waitSignal()
}
Example #3
0
func main() {
	var cmdConfig ss.Config
	var printVer bool

	flag.BoolVar(&printVer, "version", false, "print version")
	flag.StringVar(&configFile, "c", "config.json", "specify config file")
	flag.StringVar(&cmdConfig.Password, "k", "", "password")
	flag.IntVar(&cmdConfig.ServerPort, "p", 0, "server port")
	flag.IntVar(&cmdConfig.Timeout, "t", 60, "connection timeout (in seconds)")
	flag.BoolVar((*bool)(&debug), "d", false, "print debug message")

	flag.Parse()

	if printVer {
		ss.PrintVersion()
		os.Exit(0)
	}

	ss.SetDebug(debug)

	var err error
	config, err = ss.ParseConfig(configFile)
	if err != nil {
		if os.IsNotExist(err) {
			log.Println("config file not found, using all options from command line")
		} else {
			log.Printf("error reading %s: %v\n", configFile, err)
			os.Exit(1)
		}
		config = &cmdConfig
	} else {
		ss.UpdateConfig(config, &cmdConfig)
	}

	if err = unifyPortPassword(config); err != nil {
		os.Exit(1)
	}

	initTableCache(config)
	for port, password := range config.PortPassword {
		go run(port, password)
	}
	// Wait all ports have get it's encryption table
	for int(table.getCnt) != len(config.PortPassword) {
		time.Sleep(1 * time.Second)
	}
	storeTableCache(config)
	log.Println("all ports ready")

	table.cache = nil // release memory
	waitSignal()
}
Example #4
0
func main() {
	log.SetOutput(os.Stdout)

	var printVer bool
	var core int
	var serverPort string
	var redisServer string
	var timeout int

	flag.BoolVar(&printVer, "version", false, "print version")
	flag.StringVar(&serverPort, "p", "8388", "server port")
	flag.StringVar(&redisServer, "redis", ":6379", "redis server")
	flag.IntVar(&core, "core", 0, "maximum number of CPU cores to use, default is determinied by Go runtime")
	flag.IntVar(&timeout, "timeout", 10, "Socket read timeout")
	flag.BoolVar((*bool)(&debug), "d", false, "print debug message")

	flag.Parse()

	if printVer {
		ss.PrintVersion()
		os.Exit(0)
	}

	ss.SetDebug(debug)

	storage = NewStorage(redisServer)
	if core > 0 {
		runtime.GOMAXPROCS(core)
	}

	readTimeout = time.Duration(timeout) * time.Second

	go run(serverPort)

	waitSignal()
}
Example #5
0
func initLog() {
	logFile = os.Stdout
	if config.LogFile != "" {
		if f, err := os.OpenFile(expandTilde(config.LogFile),
			os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600); err != nil {
			fmt.Printf("Can't open log file, logging to stdout: %v\n", err)
		} else {
			logFile = f
		}
	}
	log.SetOutput(logFile)
	if colorize {
		color.SetDefaultColor(color.ANSI)
	} else {
		color.SetDefaultColor(color.NoColor)
	}
	errorLog = log.New(logFile, color.Red("[ERROR] "), log.LstdFlags)
	debugLog = log.New(logFile, color.Blue("[DEBUG] "), log.LstdFlags)
	if debug {
		ss.SetDebug(ss.DebugLog(true))
	}
	requestLog = log.New(logFile, color.Green("[>>>>>] "), log.LstdFlags)
	responseLog = log.New(logFile, color.Yellow("[<<<<<] "), log.LstdFlags)
}
Example #6
0
func main() {
	log.SetOutput(os.Stdout)

	var configFile, cmdServer string
	var cmdConfig ss.Config
	var printVer bool

	flag.BoolVar(&printVer, "version", false, "print version")
	flag.StringVar(&configFile, "c", "config.json", "specify config file")
	flag.StringVar(&cmdServer, "s", "", "server address")
	flag.StringVar(&cmdConfig.Password, "k", "", "password")
	flag.IntVar(&cmdConfig.ServerPort, "p", 0, "server port")
	flag.IntVar(&cmdConfig.LocalPort, "l", 0, "local socks5 proxy port")
	flag.StringVar(&cmdConfig.Method, "m", "", "encryption method, use empty string or rc4")
	flag.BoolVar((*bool)(&debug), "d", false, "print debug message")

	flag.Parse()

	if printVer {
		ss.PrintVersion()
		os.Exit(0)
	}

	cmdConfig.Server = cmdServer
	ss.SetDebug(debug)

	exists, err := ss.IsFileExists(configFile)
	// If no config file in current directory, try search it in the binary directory
	// Note there's no portable way to detect the binary directory.
	binDir := path.Dir(os.Args[0])
	if (!exists || err != nil) && binDir != "" && binDir != "." {
		oldConfig := configFile
		configFile = path.Join(binDir, "config.json")
		log.Printf("%s not found, try config file %s\n", oldConfig, configFile)
	}

	config, err := ss.ParseConfig(configFile)
	if err != nil {
		config = &cmdConfig
		if !os.IsNotExist(err) {
			fmt.Fprintf(os.Stderr, "error reading %s: %v\n", configFile, err)
			os.Exit(1)
		}
	} else {
		ss.UpdateConfig(config, &cmdConfig)
	}

	if len(config.ServerPassword) == 0 {
		if !enoughOptions(config) {
			fmt.Fprintln(os.Stderr, "must specify server address, password and both server/local port")
			os.Exit(1)
		}
	} else {
		if config.Password != "" || config.ServerPort != 0 || config.GetServerArray() != nil {
			fmt.Fprintln(os.Stderr, "given server_password, ignore server, server_port and password option:", config)
		}
		if config.LocalPort == 0 {
			fmt.Fprintln(os.Stderr, "must specify local port")
			os.Exit(1)
		}
	}

	parseServerConfig(config)

	run(strconv.Itoa(config.LocalPort))
}
Example #7
0
func (s ShadowsocksTransport) Start() error {
	handler := server.NewHandler(s.Name)

	listener, err := net.Listen("tcp", s.BindAddr)
	if err != nil {
		listener, err = net.Listen("tcp", "127.0.0.1:0")
	}
	if err != nil {
		handler.PrintError("CANNOT BIND TO ANY PORT")
		return errors.New("Cannot bind to any port")
	}

	listener = handler.MonitorListener(listener)
	handler.PrintExpose("socks5", listener.Addr().String())

	config := &ss.Config{
		Server:     s.RemoteHost,
		ServerPort: s.RemotePort,
		Password:   s.Secret,
		LocalPort:  s.BindPort,
		Method:     "aes-256-cfb",
	}

	parseServerConfig(config)

	handler.PrintDone()

	verbose := server.NewOption("verbose")

	if verbose.Has() {
		s.Verbose = true
		ss.SetDebug(true)
		debug = true
	}

	go func() {
		for {
			defer listener.Close()
			conn, err := listener.Accept()
			if err != nil {
				debug.Println("accept:", err)
				continue
			}
			go func(conn net.Conn) {
				conn = handler.MonitorConn(conn)
				if debug {
					debug.Printf("socks connect from %s\n", conn.RemoteAddr().String())
				}
				closed := false
				defer func() {
					if !closed {
						conn.Close()
					}
				}()

				var err error = nil
				if err = handShake(conn); err != nil {
					debug.Printf("socks handshake: %s", err)
					return
				}
				rawaddr, addr, err := getRequest(conn)
				if err != nil {
					debug.Println("error getting request:", err)
					return
				}
				// Sending connection established message immediately to client.
				// This some round trip time for creating socks connection with the client.
				// But if connection failed, the client will get connection reset error.
				_, err = conn.Write([]byte{0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x43})
				if err != nil {
					debug.Println("send connection confirmation:", err)
					return
				}

				remote, err := createServerConn(rawaddr, addr)
				if err != nil {
					if len(servers.srvCipher) > 1 {
						debug.Println("Failed connect to all avaiable shadowsocks server")
					}
					return
				}
				handler.TrackOpenConn(addr)
				defer func() {
					if !closed {
						remote.Close()
					}
				}()

				go ss.PipeThenClose(conn, remote)
				ss.PipeThenClose(remote, conn)
				closed = true
				handler.TrackCloseConn(addr)

			}(conn)
		}
	}()
	handler.Wait()
	return nil
}
Example #8
0
func main() {
	log.SetOutput(os.Stdout)

	var cmdConfig ss.Config
	var printVer, debug bool
	var core int

	flag.BoolVar(&printVer, "version", false, "print version")
	flag.StringVar(&configFile, "c", "config.json", "specify config file")
	flag.StringVar(&cmdConfig.Password, "k", "", "password")
	flag.IntVar(&cmdConfig.ServerPort, "p", 0, "server port")
	flag.IntVar(&cmdConfig.Timeout, "t", 60, "connection timeout (in seconds)")
	flag.StringVar(&cmdConfig.Method, "m", "", "encryption method, default: aes-256-cfb")
	flag.IntVar(&cmdConfig.Net, "n", 0, "ipv4(4) or ipv6(6) or both(0), default is both")
	flag.IntVar(&core, "core", 0, "maximum number of CPU cores to use, default is determinied by logical CPUs on server")
	flag.BoolVar(&udp, "u", false, "UDP Relay")
	flag.BoolVar(&debug, "d", false, "print debug message")
	flag.Parse()

	if printVer {
		ss.PrintVersion()
		os.Exit(0)
	}

	ss.SetDebug(debug)

	var err error
	config, err = ss.ParseConfig(configFile)
	if err != nil {
		if !os.IsNotExist(err) {
			fmt.Fprintf(os.Stderr, "error reading %s: %v\n", configFile, err)
			os.Exit(1)
		}
		config = &cmdConfig
	} else {
		ss.UpdateConfig(config, &cmdConfig)
	}
	switch config.Net {
	case 4:
		netTcp = "tcp4"
		netUdp = "udp4"
	case 6:
		netTcp = "tcp6"
		netUdp = "udp6"
	default:
		netTcp = "tcp"
		netUdp = "udp"
	}
	if config.Method == "" {
		config.Method = "aes-256-cfb"
	}
	if err = ss.CheckCipherMethod(config.Method); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	if err = unifyPortPassword(config); err != nil {
		os.Exit(1)
	}
	if core > 0 {
		runtime.GOMAXPROCS(runtime.NumCPU())
	}
	ss.NewTraffic()
	for port, password := range config.PortPassword {
		go run(port, password)
		if udp && password[2] == "ok" {
			go runUDP(port, password)
		}
	}

	waitSignal()
}
Example #9
0
func main() {
	log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
	log.SetOutput(os.Stdout)

	var cmdConfig ss.Config
	var printVer bool
	var core int

	flag.BoolVar(&printVer, "version", false, "print version")
	flag.StringVar(&configFile, "c", "config.json", "specify config file")
	flag.StringVar(&cmdConfig.Password, "k", "", "password")
	flag.IntVar(&cmdConfig.ServerPort, "p", 0, "server port")
	flag.IntVar(&cmdConfig.Timeout, "t", 60, "connection timeout (in seconds)")
	flag.StringVar(&cmdConfig.Method, "m", "", "encryption method, default: aes-256-cfb")
	flag.IntVar(&core, "core", 0, "maximum number of CPU cores to use, default is determinied by Go runtime")
	flag.BoolVar((*bool)(&debug), "d", false, "print debug message")

	flag.Parse()

	if printVer {
		ss.PrintVersion()
		os.Exit(0)
	}

	ss.SetDebug(debug)

	var err error
	config, err = ss.ParseConfig(configFile)
	if err != nil {
		if !os.IsNotExist(err) {
			fmt.Fprintf(os.Stderr, "error reading %s: %v\n", configFile, err)
			os.Exit(1)
		}
		config = &cmdConfig
	} else {
		ss.UpdateConfig(config, &cmdConfig)
	}
	if config.Method == "" {
		config.Method = "aes-256-cfb"
	}
	if err = ss.CheckCipherMethod(config.Method); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	if err = unifyPortPassword(config); err != nil {
		os.Exit(1)
	}
	if core > 0 {
		runtime.GOMAXPROCS(core)
	}

	initPortMap()
	if runtime.GOOS == "linux" {
		limitConfig.Init("/etc/limit.json")
	} else {
		limitConfig.Init("limit.json")
	}

	for port, password := range config.PortPassword {
		go run(port, password)
	}

	go runWeb()
	go DaysLimitLoop()

	waitSignal()
}