diff --git a/api/common/interfaces.go b/api/common/interfaces.go
index 543f87fc6..7fa655e7b 100644
--- a/api/common/interfaces.go
+++ b/api/common/interfaces.go
@@ -5,6 +5,8 @@ import (
"encoding/hex"
"encoding/json"
"math"
+ "net"
+ "strings"
"github.com/gogo/protobuf/proto"
"github.com/nknorg/nkn/common"
@@ -1154,6 +1156,32 @@ func getTopicBucketsCount(s Serverer, params map[string]interface{}) map[string]
return respPacking(count, SUCCESS)
}
+// getMyExtIP get RPC client's external IP
+// params: ["address":
]
+// return: {"result":, "error":}
+func getMyExtIP(s Serverer, params map[string]interface{}) map[string]interface{} {
+ if len(params) < 1 {
+ return respPacking(nil, INVALID_PARAMS)
+ }
+
+ addr, ok := params["RemoteAddr"].(string)
+ if !ok || len(addr) == 0 {
+ log.Errorf("Invalid params: [%v, %v]", ok, addr)
+ return respPacking(nil, INVALID_PARAMS)
+ }
+
+ host, _, err := net.SplitHostPort(addr)
+ if err != nil {
+ if strings.LastIndexByte(addr, ':') >= 0 {
+ log.Errorf("getMyExtIP met invalid params %v: %v", addr, err)
+ return respPacking(nil, INVALID_PARAMS)
+ }
+ host = addr // addr just only host, without port
+ }
+ ret := map[string]interface{}{"RemoteAddr": host}
+ return respPacking(ret, SUCCESS)
+}
+
// findSuccessorAddrs find the successors of a key
// params: ["address":]
// return: {"result":, "error":}
@@ -1254,6 +1282,7 @@ var InitialAPIHandlers = map[string]APIHandler{
"getsubscribers": {Handler: getSubscribers, AccessCtrl: BIT_JSONRPC},
"getfirstavailabletopicbucket": {Handler: getFirstAvailableTopicBucket, AccessCtrl: BIT_JSONRPC},
"gettopicbucketscount": {Handler: getTopicBucketsCount, AccessCtrl: BIT_JSONRPC},
+ "getmyextip": {Handler: getMyExtIP, AccessCtrl: BIT_JSONRPC},
"findsuccessoraddr": {Handler: findSuccessorAddr, AccessCtrl: BIT_JSONRPC},
"findsuccessoraddrs": {Handler: findSuccessorAddrs, AccessCtrl: BIT_JSONRPC},
}
diff --git a/api/httpjson/RPCserver.go b/api/httpjson/RPCserver.go
index 0ed425110..a8b08a0f8 100644
--- a/api/httpjson/RPCserver.go
+++ b/api/httpjson/RPCserver.go
@@ -109,6 +109,19 @@ func (s *RPCServer) Handle(w http.ResponseWriter, r *http.Request) {
w.Write(data)
return
}
+ // if params["RemoteAddr"] set but empty, used request.RemoteAddr
+ if addr, ok := params["RemoteAddr"]; ok {
+ switch addr.(type) {
+ case []byte, string:
+ if len(addr.(string)) == 0 { // empty string
+ params["RemoteAddr"] = r.RemoteAddr
+ }
+ case bool: // save remoteAddr whatever true or false
+ params["RemoteAddr"] = r.RemoteAddr
+ default:
+ log.Warningf("RemoteAddr unsupport type for %v", addr)
+ }
+ }
//get the corresponding function
function, ok := s.mainMux.m[method]