diff --git a/features/mml/mml.go b/features/mml/mml.go index 99dbdc76..eeb10047 100644 --- a/features/mml/mml.go +++ b/features/mml/mml.go @@ -112,21 +112,8 @@ func PostMMLToNF(w http.ResponseWriter, r *http.Request) { } if neInfo != nil { - hostMML := fmt.Sprintf("%s:%d", neInfo.Ip, config.GetYamlConfig().MML.Port) - conn, err := net.Dial("tcp", hostMML) - if err != nil { - errMsg := fmt.Sprintf("Failed to dial %s: %v", hostMML, err) - log.Error(errMsg) - mmlResult = append(mmlResult, errMsg) - response := Response{mmlResult} - services.ResponseWithJson(w, http.StatusOK, response) - return - } - defer conn.Close() - - conn.SetDeadline(time.Now().Add(10 * time.Second)) switch strings.ToLower(neType) { - case "upf": + case "xxx": body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen)) if err != nil { log.Error("io.ReadAll is failed:", err) @@ -148,16 +135,29 @@ func PostMMLToNF(w http.ResponseWriter, r *http.Request) { // } // log.Debug(string(buf[0:n])) - loginStr := fmt.Sprintf("%s\n%s\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password) - _, err = conn.Write([]byte(loginStr)) - if err != nil { - log.Error("Failed to write:", err) - mmlResult = append(mmlResult, err.Error()) - response := Response{mmlResult} - services.ResponseWithJson(w, http.StatusOK, response) - return - } - time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE) + // hostMML := fmt.Sprintf("%s:%d", neInfo.Ip, config.GetYamlConfig().MML.Port) + // conn, err := net.Dial("tcp", hostMML) + // if err != nil { + // errMsg := fmt.Sprintf("Failed to dial %s: %v", hostMML, err) + // log.Error(errMsg) + // mmlResult = append(mmlResult, errMsg) + // response := Response{mmlResult} + // services.ResponseWithJson(w, http.StatusOK, response) + // return + // } + // defer conn.Close() + + // conn.SetDeadline(time.Now().Add(10 * time.Second)) + // loginStr := fmt.Sprintf("%s\n%s\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password) + // _, err = conn.Write([]byte(loginStr)) + // if err != nil { + // log.Error("Failed to write:", err) + // mmlResult = append(mmlResult, err.Error()) + // response := Response{mmlResult} + // services.ResponseWithJson(w, http.StatusOK, response) + // return + // } + // time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE) // n, err = conn.Write([]byte(config.GetYamlConfig().MML.User + "\n")) // if err != nil { @@ -203,6 +203,30 @@ func PostMMLToNF(w http.ResponseWriter, r *http.Request) { // log.Debug(string(buf[0:n])) for _, mml := range mmlRequest.MML { + hostMML := fmt.Sprintf("%s:%d", neInfo.Ip, config.GetYamlConfig().MML.Port) + conn, err := net.Dial("tcp", hostMML) + if err != nil { + errMsg := fmt.Sprintf("Failed to dial %s: %v", hostMML, err) + log.Error(errMsg) + mmlResult = append(mmlResult, errMsg) + response := Response{mmlResult} + services.ResponseWithJson(w, http.StatusOK, response) + return + } + defer conn.Close() + + conn.SetDeadline(time.Now().Add(10 * time.Second)) + + loginStr := fmt.Sprintf("%s\n%s\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password) + _, err = conn.Write([]byte(loginStr)) + if err != nil { + log.Error("Failed to write:", err) + mmlResult = append(mmlResult, err.Error()) + response := Response{mmlResult} + services.ResponseWithJson(w, http.StatusOK, response) + return + } + time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE) mmlCommand := fmt.Sprintf("%s\n", mml) log.Debug("mml command:", mmlCommand) _, err = conn.Write([]byte(mmlCommand)) @@ -233,12 +257,157 @@ func PostMMLToNF(w http.ResponseWriter, r *http.Request) { result := re1.ReplaceAllString(string(buf[config.GetYamlConfig().MML.UpfHeaderLength:n-len(neType)-2]), "") result = re2.ReplaceAllString(result, "") mmlResult = append(mmlResult, result) + conn.Close() //mmlResult = append(mmlResult, string(buf[0:n-len(neType)-2])) // can't read buffer from upf telnet server, so return ok always // mmlResult = append(mmlResult, "COMMAND OK\n") } + case "ims": + body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen)) + if err != nil { + log.Error("io.ReadAll is failed:", err) + services.ResponseNotFound404UriNotExist(w, r) + return + } + log.Trace("Body:", string(body)) + + mmlRequest := new(MMLRequest) + _ = json.Unmarshal(body, mmlRequest) + + for _, mml := range mmlRequest.MML { + hostMML := fmt.Sprintf("%s:%d", neInfo.Ip, config.GetYamlConfig().MML.Port) + conn, err := net.Dial("tcp", hostMML) + if err != nil { + errMsg := fmt.Sprintf("Failed to dial %s: %v", hostMML, err) + log.Error(errMsg) + mmlResult = append(mmlResult, errMsg) + response := Response{mmlResult} + services.ResponseWithJson(w, http.StatusOK, response) + return + } + defer conn.Close() + + // localAddr := conn.LocalAddr() + // remoteAddr := conn.RemoteAddr() + // if localAddr == nil || remoteAddr == nil { + // errMsg := fmt.Sprintf("connect invalid: localAddr=%v, remoteAddr=%v", localAddr, remoteAddr) + // log.Error(errMsg) + // mmlResult = append(mmlResult, errMsg) + // response := Response{mmlResult} + // services.ResponseWithJson(w, http.StatusOK, response) + // return + // } + conn.SetDeadline(time.Now().Add(10 * time.Second)) + + _, err = conn.Write([]byte(config.GetYamlConfig().MML.User + "\n")) + if err != nil { + log.Error("Failed to write:", err) + mmlResult = append(mmlResult, err.Error()) + response := Response{mmlResult} + services.ResponseWithJson(w, http.StatusOK, response) + return + } + time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE) + + n, err = conn.Read(buf[0:]) + if err != nil { + log.Error("Failed to read:", err) + mmlResult = append(mmlResult, err.Error()) + response := Response{mmlResult} + services.ResponseWithJson(w, http.StatusOK, response) + return + } + log.Debug(string(buf[0:n])) + + _, err = conn.Write([]byte(config.GetYamlConfig().MML.Password + "\n")) + if err != nil { + log.Error("Failed to write:", err) + mmlResult = append(mmlResult, err.Error()) + response := Response{mmlResult} + services.ResponseWithJson(w, http.StatusOK, response) + return + } + time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE) + + // loginStr := fmt.Sprintf("%s\n%s\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password) + // _, err = conn.Write([]byte(loginStr)) + // if err != nil { + // log.Error("Failed to write:", err) + // mmlResult = append(mmlResult, err.Error()) + // response := Response{mmlResult} + // services.ResponseWithJson(w, http.StatusOK, response) + // return + // } + + n, err = conn.Read(buf[0:]) + if err != nil { + log.Error("Failed to read:", err) + mmlResult = append(mmlResult, err.Error()) + response := Response{mmlResult} + services.ResponseWithJson(w, http.StatusOK, response) + return + } + log.Trace(string(buf[0 : n-len(neType)-2])) + + mmlCommand := fmt.Sprintf("%s\n", mml) + log.Debug("mml command:", mmlCommand) + _, err = conn.Write([]byte(mmlCommand)) + if err != nil { + log.Error("Failed to write:", err) + mmlResult = append(mmlResult, err.Error()) + response := Response{mmlResult} + services.ResponseWithJson(w, http.StatusOK, response) + return + } + time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE) + + n, err = conn.Read(buf[0:]) + if err != nil { + log.Error("Failed to read:", err) + mmlResult = append(mmlResult, err.Error()) + response := Response{mmlResult} + services.ResponseWithJson(w, http.StatusOK, response) + return + } + log.Trace(string(buf[0 : n-len(neType)-2])) + + re1 := regexp.MustCompile(`\x1B\[[0-9;]*[a-zA-Z]`) // 匹配包含␛的控制字符 + //re2 := regexp.MustCompile(`\x00`) // 匹配空字符 + re2 := regexp.MustCompile(`[\x00-\x08\x0B\x0C\x0E-\x1F\x7F\x1B]`) // 匹配空字符和包含␛的控制字符 + //re := regexp.MustCompile(`[\x00-\x1F\x7F]`) + // upf telnet buffer只能读取一次,需要去掉前面的多余字符 + //result := re1.ReplaceAllString(string(buf[0:n-len(neType)-2]), "") + result := re1.ReplaceAllString(string(buf[0:]), "") + result = re2.ReplaceAllString(result, "") + mmlResult = append(mmlResult, result) + conn.Close() + } default: + hostMML := fmt.Sprintf("%s:%d", neInfo.Ip, config.GetYamlConfig().MML.Port) + conn, err := net.Dial("tcp", hostMML) + if err != nil { + errMsg := fmt.Sprintf("Failed to dial %s: %v", hostMML, err) + log.Error(errMsg) + mmlResult = append(mmlResult, errMsg) + response := Response{mmlResult} + services.ResponseWithJson(w, http.StatusOK, response) + return + } + defer conn.Close() + + // localAddr := conn.LocalAddr() + // remoteAddr := conn.RemoteAddr() + // if localAddr == nil || remoteAddr == nil { + // errMsg := fmt.Sprintf("connect invalid: localAddr=%v, remoteAddr=%v", localAddr, remoteAddr) + // log.Error(errMsg) + // mmlResult = append(mmlResult, errMsg) + // response := Response{mmlResult} + // services.ResponseWithJson(w, http.StatusOK, response) + // return + // } + + conn.SetDeadline(time.Now().Add(10 * time.Second)) loginStr := fmt.Sprintf("%s\n%s\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password) _, err = conn.Write([]byte(loginStr)) if err != nil {