aboutsummaryrefslogtreecommitdiff
path: root/vendor/syscon
diff options
context:
space:
mode:
authorSina Ghaderi <32870524+Sina-Ghaderi@users.noreply.github.com>2021-03-19 08:06:20 +0330
committerGitHub <noreply@github.com>2021-03-19 08:06:20 +0330
commitb8bb371ca118aa63785adffd98bb24cc1113f1c5 (patch)
tree00bab7b7194f92bee0e831958e34c099efbf80ff /vendor/syscon
parente16ec4f65419aefa0bb401d6af2e30be0d6bfa25 (diff)
pushing to git services
Diffstat (limited to 'vendor/syscon')
-rw-r--r--vendor/syscon/syscon.go203
1 files changed, 203 insertions, 0 deletions
diff --git a/vendor/syscon/syscon.go b/vendor/syscon/syscon.go
new file mode 100644
index 0000000..50254e0
--- /dev/null
+++ b/vendor/syscon/syscon.go
@@ -0,0 +1,203 @@
+package syscon
+
+import (
+ "bufio"
+ "bytes"
+ "config"
+ "datax"
+ "errors"
+ "fmt"
+ "net"
+ "os"
+ "path/filepath"
+ "regexp"
+ "strconv"
+ "strings"
+ "syslog"
+ "time"
+)
+
+func StartNewService(conf *config.Config) {
+ if err := datax.SQLInit(conf); err != nil {
+ panic(syslog.BigError{Why: err, Cod: 1})
+ }
+ defer datax.DBClose()
+ lisfunc, isthere := networkListenType[conf.GetConf("listener_type", 0)]
+ if !isthere {
+ panic(syslog.BigError{Why: errors.New("invalid listener_type in config file, should be either inet or unix"), Cod: 1})
+ }
+ l := lisfunc(conf)
+ defer l.Close()
+ syslog.InformGreen("connection to sql server established")
+ syn := regexp.MustCompile(`(^sasl_username=.*[^\s].*)$`)
+
+ for {
+ conn, err := l.Accept()
+ if err != nil {
+ syslog.InformError(err)
+ continue
+ }
+
+ go handlePostfixConn(conn, syn)
+ }
+
+}
+
+func handlePostfixConn(conn net.Conn, syn *regexp.Regexp) {
+ defer conn.Close()
+ scanner := bufio.NewScanner(conn)
+ for scanner.Scan() {
+ if find := syn.MatchString(scanner.Text()); find {
+ pureName := strings.ReplaceAll(scanner.Text(), "sasl_username=", "")
+ userAcc, err := datax.GetUserFromDatabase(&pureName)
+ if err != nil {
+ syslog.InformError(err)
+ _, err := conn.Write([]byte("action=REJECT fixrate error: internal server error <1>, contact administrator\n\n"))
+ if err != nil {
+ syslog.InformError(err)
+ return
+ }
+ continue
+ }
+
+ if userAcc.LastReset.Add(time.Duration(userAcc.Reset) * time.Second).Before(time.Now()) {
+ if err := userAcc.UpdateUserLastReset(time.Now()); err != nil {
+ syslog.InformError(err)
+ _, err := conn.Write([]byte("action=REJECT fixrate error: internal server error <2>, contact administrator\n\n"))
+ if err != nil {
+ syslog.InformError(err)
+ return
+ }
+ continue
+ }
+
+ if err := userAcc.UpdateUserCounter(0); err != nil {
+ syslog.InformError(err)
+ _, err := conn.Write([]byte("action=REJECT fixrate error: internal server error <3>, contact administrator\n\n"))
+ if err != nil {
+ syslog.InformError(err)
+ return
+ }
+ continue
+ }
+ userAcc.Counter = 0
+ }
+ if userAcc.Limit <= userAcc.Counter {
+ diff := userAcc.LastReset.Add(time.Duration(userAcc.Reset) * time.Second).Sub(time.Now())
+ _, err := conn.Write([]byte(fmt.Sprintf("action=REJECT fixrate: sending limit exceeded, you can't send anything until next %v\n\n", diff.Round(time.Second))))
+ if err != nil {
+ syslog.InformError(err)
+ return
+ }
+ continue
+ }
+ if err := userAcc.UpdateUserCounter(userAcc.Counter + 1); err != nil {
+ syslog.InformError(err)
+ _, err := conn.Write([]byte("action=REJECT fixrate error: internal server error <4>, contact administrator\n\n"))
+ if err != nil {
+ syslog.InformError(err)
+ return
+ }
+ continue
+ }
+ if _, err := conn.Write([]byte("action=OK\n\n")); err != nil {
+ syslog.InformError(err)
+ return
+ }
+ }
+ }
+ if err := scanner.Err(); err != nil {
+ panic(syslog.BigError{Why: err, Cod: 1})
+ }
+}
+
+func checkUinixSocket(socketAddr string) (string, bool) {
+ unix, err := os.Open("/proc/net/unix")
+ if err != nil {
+ panic(syslog.BigError{Why: err, Cod: 1})
+ }
+ defer unix.Close()
+ u := bufio.NewScanner(unix)
+ for u.Scan() {
+ if bytes.Contains(u.Bytes(), []byte(socketAddr)) {
+ pid := findPid(strings.Fields(u.Text())[6])
+ return pid, true
+ }
+ }
+ if err := u.Err(); err != nil {
+ panic(syslog.BigError{Why: err, Cod: 1})
+ }
+ return "", false
+}
+
+var networkListenType = map[string]func(conf *config.Config) net.Listener{
+ "unix": func(conf *config.Config) net.Listener {
+ socketAddr := conf.GetConf("socket_path", 0)
+ if pid, exists := checkUinixSocket(socketAddr); exists {
+ panic(syslog.BigError{Why: fmt.Errorf("unix socket %v is held by another process (pid: %v), is another fixrate daemon runing?", socketAddr, pid), Cod: 1})
+ }
+ if err := os.RemoveAll(socketAddr); err != nil {
+ panic(syslog.BigError{Why: err, Cod: 1})
+ }
+ SockPerm, err := strconv.Atoi(conf.GetConf("socket_perm", 0))
+ if err != nil {
+ panic(syslog.BigError{Why: errors.New("socket_path should hold an integer"), Cod: 1})
+ }
+ l, err := net.Listen("unix", socketAddr)
+ if err != nil {
+ panic(syslog.BigError{Why: err, Cod: 1})
+ }
+
+ mod := os.FileMode(SockPerm)
+ if err = os.Chmod(socketAddr, mod); err != nil {
+ l.Close()
+ panic(syslog.BigError{Why: err, Cod: 1})
+ }
+ syslog.InformGreen("start listening on unix socket", socketAddr)
+ return l
+ },
+ "inet": func(conf *config.Config) net.Listener {
+ listenAddr := conf.GetConf("listen_addr", 0)
+ l, err := net.Listen("tcp", listenAddr)
+ if err != nil {
+ panic(syslog.BigError{Why: err, Cod: 1})
+ }
+ syslog.InformGreen("start listening on tcp address", listenAddr)
+ return l
+ },
+}
+
+func findPid(inode string) string {
+ type sysInodes struct {
+ path string
+ link string
+ }
+ var pid string
+ fd, err := filepath.Glob("/proc/[0-9]*/fd/[0-9]*")
+ if err != nil {
+ return pid
+ }
+
+ inodes := make([]sysInodes, len(fd))
+ mx := make(chan sysInodes, len(fd))
+
+ go func(fd *[]string, outchan chan<- sysInodes) {
+ for _, item := range *fd {
+ link, _ := os.Readlink(item)
+ outchan <- sysInodes{item, link}
+ }
+ }(&fd, mx)
+
+ for range fd {
+ inodes = append(inodes, <-mx)
+ }
+
+ re := regexp.MustCompile(inode)
+ for _, item := range inodes {
+ out := re.FindString(item.link)
+ if len(out) != 0 {
+ pid = strings.Split(item.path, "/")[2]
+ }
+ }
+ return pid
+}

Snix LLC Git Repository Holder Copyright(C) 2022 All Rights Reserved Email To Snix.IR