Beispiel #1
0
func ServerSocket() {
	addr, err := net.ResolveTCPAddr("tcp", config.Listen_addr)
	if err != nil {
		log.Fatalf("error parse address %s: %s", config.Listen_addr, err.Error())
	}
	s, err := net.ListenTCP("tcp", addr)
	if err != nil {
		log.Fatalf("error listening on %s: %s", config.Listen_addr, err.Error())
	}
	log.Infof("Server listened on %s", config.Listen_addr)
	for {
		conn, err := s.AcceptTCP()
		if err != nil {
			log.Warnf("listen_socket: error when accepting: %s", err.Error())
			continue
		}
		go func(conn *WrapedSocket) {
			event := new(PostAcceptEvent)
			event.RemoteAddr = conn.RemoteAddr().(*net.TCPAddr)
			event.connID = conn.Id()
			PostAccept(event)
			if event.Rejected() {
				conn.Warnf("connection rejected.")
				conn.Close()
				return
			}
			log.Infof("connection accepted.")
			ClientSocket(conn, event)
		}(WrapClientSocket(conn))
	}
}
Beispiel #2
0
func ConfReload() {
	// Do not panic!
	defer func() {
		if r := recover(); r != nil {
			log.Errorf("paniced when reloading config %s, recovered.", config_file)
			log.Errorf("panic: %s", r)
		}
	}()
	log.Warn("Reloading config")
	content, err := ioutil.ReadFile(config_file)
	if err != nil {
		log.Errorf("unable to reload config %s: %s", config_file, err.Error())
		return
	}
	prev_listen := config.Listen_addr
	config_lock.Lock()
	err = yaml.Unmarshal(content, &config)
	if err != nil {
		log.Errorf("error when parsing config file %s: %s", config_file, err.Error())
		return
	}
	validateConfig()
	config_lock.Unlock()
	log.Info("config reloaded.")
	if config.Listen_addr != prev_listen {
		log.Warnf("config reload will not reopen server socket, thus no effect on listen address")
	}
	log.Infof("%d upstream server(s) found", len(config.Upstream))
}
Beispiel #3
0
func Run() {
	PreLoadConfig()
	confInit()
	PostLoadConfig()
	runtime.GOMAXPROCS(runtime.NumCPU())
	log.Infof("MineGate %s started.", version_full)
	go ServerSocket()
	sig := make(chan os.Signal, 1)
	signal.Notify(sig, syscall.SIGHUP, syscall.SIGUSR1)
	for {
		cur := <-sig
		switch cur {
		case syscall.SIGHUP:
			log.Warn("SIGHUP caught, reloading config...")
			PreLoadConfig()
			ConfReload()
			PostLoadConfig()
		case syscall.SIGUSR1:
			log.Warn("SIGUSR1 caught, rotating log...")
			log.Rotate()
		default:
			log.Errorf("Trapped unexpected signal: %s", cur.String())
			continue
		}
	}
}
Beispiel #4
0
func PipeIt(reader *WrapedSocket, writer *WrapedSocket) {
	// TODO: Use configurable buffer size.
	raddr := reader.RemoteAddr().String()
	waddr := writer.RemoteAddr().String()
	log.Infof("%s ==PIPE==> %s", raddr, waddr)
	defer writer.Close()
	buffer := make([]byte, 4096)
	for {
		reader.SetTimeout(15 * time.Second)
		n, err := reader.Read(buffer)
		if err != nil {
			if err == io.EOF {
				reader.Warnf("EOF, closing connection.")
			} else {
				reader.Errorf("read error: %s", err.Error())
			}
			reader.Close()
			if n > 0 {
				writer.SetWriteTimeout(15 * time.Second)
				writer.Write(buffer[:n])
			}
			return
		}
		writer.SetWriteTimeout(15 * time.Second)
		n, err = writer.Write(buffer[:n])
		if err != nil {
			writer.Errorf("write error: %s", err.Error())
			return
		}
		// log.Debugf("%s == %d bytes => %s", raddr, n, waddr)
	}
}
Beispiel #5
0
func (upstream *Upstream) Validate() (valid bool) {
	var host, port string
	host, port, err := net.SplitHostPort(upstream.Server)
	if err != nil {
		server := upstream.Server + ":25565"
		if host, port, err = net.SplitHostPort(server); err != nil {
			log.Error("Invalid upstream server: " + upstream.Server)
			return false
		}
		log.Infof("no port information found in %s, assume 25565", upstream.Server)
		upstream.Server = server
	}
	p, err := strconv.ParseUint(port, 10, 16)
	if err != nil {
		log.Errorf("Invalid port %s: %s", port, err.Error())
		return false
	}
	host = strings.ToLower(host)
	if !CheckHost(host) {
		log.Error("Invalid upstream host: " + host)
		return false
	}
	upstream.Server = net.JoinHostPort(host, fmt.Sprintf("%d", p))
	upstream.Pattern = strings.ToLower(upstream.Pattern)
	if !CheckPattern(upstream.Pattern) {
		log.Error("Invalid pattern: " + upstream.Pattern)
		return false
	}
	if upstream.ErrorMsg.Text == "" {
		log.Warnf("Empty error text for %s, use default string", upstream.Server)
		upstream.ErrorMsg.Text = "Connection failed to " + upstream.Server
	}
	upstream.ChatMsg = ToChatMsg(&upstream.ErrorMsg)
	return true
}
Beispiel #6
0
func Run() {
	PreLoadConfig()
	confInit()
	PostLoadConfig()
	runtime.GOMAXPROCS(runtime.NumCPU())
	log.Infof("MineGate %s started.", version_full)
	ServerSocket()
}
Beispiel #7
0
func heartBeatTicker() {
	for {
		time.Sleep(time.Second * time.Duration(delta))
		if limit == 0 {
			continue
		}
		ctlock.Lock()
		log.Infof("[conntrack] Reducing connection count...")
		for track := range conn_track {
			if conn_track[track] <= limit {
				delete(conn_track, track)
				log.Debugf("[conntrack] Removing IP %s.", track)
			} else {
				conn_track[track] -= limit
			}

		}
		log.Infof("[conntrack] Done. IPs currently in record: %d", len(conn_track))
		ctlock.Unlock()
	}
}
Beispiel #8
0
func loadConfig() {
	new_brust, err := minegate.GetExtraConf("conntrack.brust")
	if err != nil {
		log.Info("[conntrack] Using default brust: 5")
		brust = 5
	} else {
		nb := minegate.ToUint(new_brust)
		log.Infof("[conntrack] Using brust: %d", nb)
		brust = nb
	}
	new_limit, err := minegate.GetExtraConf("conntrack.limit")
	if err != nil {
		log.Info("[conntrack] Using default limit: 5")
		limit = 5
	} else {
		nl := minegate.ToUint(new_limit)
		if nl != 0 {
			log.Infof("[conntrack] Using limit: %d", nl)
			limit = nl
		} else {
			log.Info("[conntrack] Limit = 0, disabling conntrack.")
			limit = 0
		}
	}
	new_delta, err := minegate.GetExtraConf("conntrack.interval")
	if err != nil {
		log.Info("[conntrack] Using default delta: 60")
		delta = 60
	} else {
		nd := minegate.ToUint(new_delta)
		if nd < 15 {
			log.Warn("[conntrack] Minimal interval is 15.")
			nd = 15
		}
		log.Infof("[conntrack] Using interval %d", nd)
		delta = nd
	}
}
Beispiel #9
0
func GetUpstream(hostname string) (upstream *Upstream, err *mcchat.ChatMsg) {
	config_lock.Lock()
	defer config_lock.Unlock()
	log.Debugf("hostname=%s", hostname)
	for _, u := range config.Upstream {
		log.Debugf("pattern=%s", u.Pattern)
		if matched, _ := path.Match(u.Pattern, hostname); matched {
			log.Infof("matched server: %s", u.Server)
			return u, nil
		}
	}
	log.Warnf("no match for %s", hostname)
	return nil, config.chatNotFound
}
Beispiel #10
0
func OnLoginRequest(handle LoginRequestFunc, priority int) (err error) {
	if priority < 0 || priority > 39 {
		log.Errorf("Invalid priority %d: not in range [0, 39]", priority)
		return fmt.Errorf("priority check failure: %d not in range [0, 39]", priority)
	}
	if handle == nil {
		log.Error("Attempt to register nil handler")
		return errors.New("Nil handler!")
	}
	if loginRequestHandlers[priority] == nil {
		loginRequestHandlers[priority] = make(loginRequestHandler, 0, 16)
	}
	loginRequestHandlers[priority] = append(loginRequestHandlers[priority], handle)
	log.Infof("Registered pingRequest handler at priority %d", priority)
	return nil
}
Beispiel #11
0
func OnDisconnect(handle DisconnectFunc, priority int) (err error) {
	if priority < 0 || priority > 39 {
		log.Errorf("Invalid priority %d: not in range [0, 39]", priority)
		return fmt.Errorf("priority check failure: %d not in range [0, 39]", priority)
	}
	if handle == nil {
		log.Error("Attempt to register nil handler")
		return errors.New("Nil handler!")
	}
	if disconnectHandlers[priority] == nil {
		disconnectHandlers[priority] = make(disconnectHandler, 0, 16)
	}
	disconnectHandlers[priority] = append(disconnectHandlers[priority], handle)
	log.Infof("Registered disconnect handler at priority %d", priority)
	return nil
}
Beispiel #12
0
func OnPreStatusResponse(handle PreStatusResponseFunc, priority int) (err error) {
	if priority < 0 || priority > 39 {
		log.Errorf("Invalid priority %d: not in range [0, 39]", priority)
		return fmt.Errorf("priority check failure: %d not in range [0, 39]", priority)
	}
	if handle == nil {
		log.Error("Attempt to register nil handler")
		return errors.New("Nil handler!")
	}
	if preStatusResponseHandlers[priority] == nil {
		preStatusResponseHandlers[priority] = make(preStatusResponseHandler, 0, 16)
	}
	preStatusResponseHandlers[priority] = append(preStatusResponseHandlers[priority], handle)
	log.Infof("Registered preStatusResponse handler at priority %d", priority)
	return nil
}
Beispiel #13
0
func OnStartProxy(handle StartProxyFunc, priority int) (err error) {
	if priority < 0 || priority > 39 {
		log.Errorf("Invalid priority %d: not in range [0, 39]", priority)
		return fmt.Errorf("priority check failure: %d not in range [0, 39]", priority)
	}
	if handle == nil {
		log.Error("Attempt to register nil handler")
		return errors.New("Nil handler!")
	}
	if startProxyHandlers[priority] == nil {
		startProxyHandlers[priority] = make(startProxyHandler, 0, 16)
	}
	startProxyHandlers[priority] = append(startProxyHandlers[priority], handle)
	log.Infof("Registered startProxy handler at priority %d", priority)
	return nil
}
Beispiel #14
0
func confInit() {
	content, err := ioutil.ReadFile(config_file)
	if err != nil {
		log.Fatalf("unable to load config %s: %s", config_file, err.Error())
	}
	err = yaml.Unmarshal(content, &config)
	if err != nil {
		log.Fatalf("error when parsing config file %s: %s", config_file, err.Error())
	}
	validateConfig()
	if config.Log.Target != "" && config.Log.Target != "-" {
		config.Log.Target, _ = filepath.Abs(config.Log.Target)
		log.Info("log path: " + config.Log.Target)
	}
	log.Stop()
	if config.Daemonize {
		Daemonize()
	}
	log.Start()
	if config.Log.Level != "" {
		level := log.ToLevel(config.Log.Level)
		if level == log.INVALID {
			log.Errorf("Invalid log level %s", config.Log.Level)
		} else {
			log.SetLogLevel(level)
		}
	}
	if config.Log.Target != "" && config.Log.Target != "-" {
		err := log.Open(config.Log.Target)
		if err != nil {
			log.Fatalf("Unable to open log %s: %s", config.Log.Target, err.Error())
		}
	}
	log.Info("config loaded.")
	log.Info("server listen on: " + config.Listen_addr)
	log.Infof("%d upstream server(s) found", len(config.Upstream))
}
Beispiel #15
0
func (event *NetworkEvent) Infof(format string, v ...interface{}) {
	if event.log_prefix == "" {
		event.log_prefix = fmt.Sprintf("[#%d %s]", event.connID, event.RemoteAddr)
	}
	log.Infof(event.log_prefix+format, v...)
}
Beispiel #16
0
func (ws *WrapedSocket) Infof(format string, v ...interface{}) {
	log.Infof(ws.log_prefix+format, v...)
}
Beispiel #17
0
func SetConfig(conf string) {
	log.Infof("using config file %s", conf)
	config_file = conf
}