tools.go_stun
2021-02-25
Parent:102fbdab34d8
tools.go_stun/main.go
* Делаем вывод удобоваримым для windows . Мелкий рефакторинг
| awgur@0 | 1 package main |
| awgur@0 | 2 |
| awgur@0 | 3 import ( |
| awgur@0 | 4 "errors" |
| awgur@0 | 5 "fmt" |
| awgur@0 | 6 "log/syslog" |
| awgur@0 | 7 "net" |
| awgur@0 | 8 "os" |
| awgur@0 | 9 "strings" |
| awgur@0 | 10 "time" |
| awgur@0 | 11 ) |
| awgur@0 | 12 |
| awgur@0 | 13 const ( |
| awgur@1 | 14 LOG_IDENT string = "net-a0fs-gostun" |
| awgur@0 | 15 ) |
| awgur@0 | 16 |
| awgur@3 | 17 const ( |
| awgur@3 | 18 LOGP_INFO = iota |
| awgur@3 | 19 LOGP_WARN |
| awgur@3 | 20 LOGP_ERR |
| awgur@3 | 21 ) |
| awgur@3 | 22 |
| awgur@3 | 23 type logMessage struct { |
| awgur@3 | 24 prio uint |
| awgur@3 | 25 msg string |
| awgur@3 | 26 } |
| awgur@3 | 27 |
| awgur@3 | 28 var log_chan = make(chan logMessage, 100) |
| awgur@3 | 29 |
| awgur@3 | 30 func log_handler() { |
| awgur@3 | 31 var err error |
| awgur@3 | 32 |
| awgur@3 | 33 log, err := syslog.New(syslog.LOG_USER, LOG_IDENT) |
| awgur@3 | 34 if err != nil { |
| awgur@3 | 35 panic(err) |
| awgur@3 | 36 } |
| awgur@3 | 37 |
| awgur@3 | 38 for log_msg := range log_chan { |
| awgur@3 | 39 switch log_msg.prio { |
| awgur@3 | 40 case LOGP_INFO: |
| awgur@3 | 41 err = log.Info(log_msg.msg) |
| awgur@3 | 42 case LOGP_WARN: |
| awgur@3 | 43 err = log.Warning(log_msg.msg) |
| awgur@3 | 44 case LOGP_ERR: |
| awgur@3 | 45 err = log.Err(log_msg.msg) |
| awgur@3 | 46 default: |
| awgur@3 | 47 err = log.Err(fmt.Sprintf("Unknown type of log priority: %v", log_msg.prio)) |
| awgur@3 | 48 } |
| awgur@3 | 49 |
| awgur@3 | 50 if err != nil { |
| awgur@3 | 51 panic(err) |
| awgur@3 | 52 } |
| awgur@3 | 53 } |
| awgur@3 | 54 } |
| awgur@3 | 55 |
| awgur@3 | 56 func log_info(msg string, vars ...interface{}) { |
| awgur@3 | 57 log_chan <- logMessage{ |
| awgur@3 | 58 prio: LOGP_INFO, |
| awgur@3 | 59 msg: fmt.Sprintf(msg, vars...)} |
| awgur@3 | 60 } |
| awgur@3 | 61 |
| awgur@3 | 62 func log_warn(msg string, vars ...interface{}) { |
| awgur@3 | 63 log_chan <- logMessage{ |
| awgur@3 | 64 prio: LOGP_WARN, |
| awgur@3 | 65 msg: fmt.Sprintf(msg, vars...)} |
| awgur@3 | 66 } |
| awgur@3 | 67 |
| awgur@3 | 68 func log_err(msg string, vars ...interface{}) { |
| awgur@3 | 69 log_chan <- logMessage{ |
| awgur@3 | 70 prio: LOGP_ERR, |
| awgur@3 | 71 msg: fmt.Sprintf(msg, vars...)} |
| awgur@3 | 72 } |
| awgur@3 | 73 |
| awgur@0 | 74 func getPort() (res string, err error) { |
| awgur@0 | 75 if len(os.Args) < 2 { |
| awgur@0 | 76 err = errors.New("No port specify") |
| awgur@0 | 77 } else { |
| awgur@0 | 78 res = fmt.Sprintf(":%s", os.Args[1]) |
| awgur@0 | 79 } |
| awgur@0 | 80 return |
| awgur@0 | 81 } |
| awgur@0 | 82 |
| awgur@0 | 83 func fail(code int, msg string) { |
| awgur@0 | 84 usage := "Usage: cmd port" |
| awgur@0 | 85 usage += "\n port: port number for listening clients" |
| awgur@0 | 86 |
| awgur@0 | 87 fmt.Fprintln(os.Stderr, msg) |
| awgur@0 | 88 fmt.Fprintln(os.Stderr, usage) |
| awgur@0 | 89 os.Exit(code) |
| awgur@0 | 90 return |
| awgur@0 | 91 } |
| awgur@0 | 92 |
| awgur@0 | 93 func handler(conn net.Conn) { |
| awgur@0 | 94 _s_tm := time.Now() |
| awgur@0 | 95 remoteAddr := conn.RemoteAddr().String() |
| awgur@4 | 96 res := "" |
| awgur@0 | 97 |
| awgur@0 | 98 defer func() { |
| awgur@0 | 99 var err error |
| awgur@0 | 100 _s_tmd := time.Now().Sub(_s_tm) |
| awgur@0 | 101 if r_err := recover(); r_err != nil { |
| awgur@3 | 102 log_err("Error on service for %s (service time: %v): %v", remoteAddr, _s_tmd, r_err) |
| awgur@0 | 103 } else { |
| awgur@0 | 104 err = conn.Close() |
| awgur@0 | 105 if err != nil { |
| awgur@3 | 106 log_err("Error on closing socket when service %s (service time: %v): %v", |
| awgur@3 | 107 remoteAddr, _s_tmd, err) |
| awgur@0 | 108 |
| awgur@0 | 109 } else { |
| awgur@3 | 110 log_info("Ok service %s in %v", remoteAddr, _s_tmd) |
| awgur@0 | 111 } |
| awgur@0 | 112 } |
| awgur@0 | 113 }() |
| awgur@0 | 114 |
| awgur@0 | 115 addr_spit := strings.Split(remoteAddr, ":") |
| awgur@0 | 116 addr_last := len(addr_spit) - 1 |
| awgur@2 | 117 addr := strings.Join(addr_spit[:addr_last], ":") |
| awgur@2 | 118 |
| awgur@2 | 119 dns_names, err := net.LookupAddr(strings.Trim(addr, "[] ")) |
| awgur@2 | 120 if err != nil { |
| awgur@3 | 121 log_warn("Fail to resolve dns name for %s: %v", remoteAddr, err) |
| awgur@2 | 122 } else { |
| awgur@2 | 123 for _, dns_name := range dns_names { |
| awgur@4 | 124 res += fmt.Sprintf("Name: %s\r\n", dns_name) |
| awgur@2 | 125 } |
| awgur@2 | 126 } |
| awgur@4 | 127 res += fmt.Sprintf("IP: %s\r\n", addr) |
| awgur@4 | 128 res += fmt.Sprintf("Port: %s\r\n", addr_spit[addr_last]) |
| awgur@4 | 129 res += "\n" |
| awgur@0 | 130 |
| awgur@4 | 131 if _, err := conn.Write([]byte(res)); err != nil { |
| awgur@1 | 132 panic(err.Error()) |
| awgur@0 | 133 } |
| awgur@0 | 134 } |
| awgur@0 | 135 |
| awgur@0 | 136 func main() { |
| awgur@0 | 137 port, err := getPort() |
| awgur@0 | 138 if err != nil { |
| awgur@0 | 139 fail(1, fmt.Sprint("Error in parsing port number: ", err)) |
| awgur@0 | 140 } |
| awgur@0 | 141 |
| awgur@3 | 142 go log_handler() |
| awgur@3 | 143 |
| awgur@0 | 144 svc, err := net.Listen("tcp", port) |
| awgur@0 | 145 if err != nil { |
| awgur@0 | 146 fail(2, fmt.Sprint("Fail to open socket: ", err)) |
| awgur@0 | 147 } |
| awgur@0 | 148 |
| awgur@0 | 149 for { |
| awgur@0 | 150 conn, err := svc.Accept() |
| awgur@0 | 151 if err != nil { |
| awgur@0 | 152 fail(1, fmt.Sprint("Error accepting connections: ", err)) |
| awgur@0 | 153 } |
| awgur@0 | 154 go handler(conn) |
| awgur@0 | 155 } |
| awgur@0 | 156 } |