Skip to content
This repository was archived by the owner on Dec 20, 2024. It is now read-only.

Commit f7d4371

Browse files
committed
feature: get LocalIP from supernode HTTP _ping API first rather than TCP connection due to Kube-service in ipvs-mod will get cluster IP for LocalAddr
1 parent f372031 commit f7d4371

File tree

9 files changed

+89
-1
lines changed

9 files changed

+89
-1
lines changed

cmd/dfdaemon/app/init.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package app
1919
import (
2020
"bytes"
2121
"fmt"
22+
api "github.com/dragonflyoss/Dragonfly/dfget/core/api"
2223
"os"
2324
"os/exec"
2425
"os/user"
@@ -62,8 +63,23 @@ func getLocalIP(nodes []string) (localIP string) {
6263
var (
6364
e error
6465
)
66+
supernodeApi := api.NewSupernodeAPI()
6567
for _, n := range nodes {
6668
ip, port := netutils.GetIPAndPortFromNode(n, dfgetcfg.DefaultSupernodePort)
69+
// step 1. query supernode api get request ip, check if request ip in local eth IPs
70+
if localIP, e = supernodeApi.Ping(fmt.Sprintf("%s:%d", ip, port)); e == nil {
71+
logrus.Infof("Connect to supernode get self ip:%s", localIP)
72+
if localIPs, err := netutils.GetAllIPs(); err == nil {
73+
for _, lip := range localIPs {
74+
if localIP == lip {
75+
return localIP
76+
}
77+
}
78+
}
79+
} else {
80+
logrus.Warnf("Connect to supernode:%s error: %v", n, e)
81+
}
82+
// step 2. if request ip not in eth ips, it might behind NAT, try use TCP conn to get localIP
6783
if localIP, e = httputils.CheckConnect(ip, port, 1000); e == nil {
6884
return localIP
6985
}

dfget/core/api/supernode_api.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232

3333
/* the url paths of supernode APIs*/
3434
const (
35+
pingPath = "/_ping"
3536
peerRegisterPath = "/peer/registry"
3637
peerPullPieceTaskPath = "/peer/task"
3738
peerReportPiecePath = "/peer/piece/suc"
@@ -53,6 +54,7 @@ func NewSupernodeAPI() SupernodeAPI {
5354

5455
// SupernodeAPI defines the communication methods between supernode and dfget.
5556
type SupernodeAPI interface {
57+
Ping(node string) (reqIP string, e error)
5658
Register(node string, req *types.RegisterRequest) (resp *types.RegisterResponse, e error)
5759
PullPieceTask(node string, req *types.PullPieceTaskRequest) (resp *types.PullPieceTaskResponse, e error)
5860
ReportPiece(node string, req *types.ReportPieceRequest) (resp *types.BaseResponse, e error)
@@ -74,6 +76,24 @@ type supernodeAPI struct {
7476

7577
var _ SupernodeAPI = &supernodeAPI{}
7678

79+
// Ping sends a request to the supernode to check if suppernode is ok
80+
// and get request ip from supernode.
81+
func (api *supernodeAPI) Ping(node string) (reqIP string, e error) {
82+
var (
83+
code int
84+
body []byte
85+
)
86+
url := fmt.Sprintf("%s://%s%s",
87+
api.Scheme, node, pingPath)
88+
if code, body, e = api.HTTPClient.Get(url, api.Timeout); e != nil {
89+
return "", e
90+
}
91+
if !httputils.HTTPStatusOk(code) {
92+
return "", fmt.Errorf("%d:%s", code, body)
93+
}
94+
return string(body), e
95+
}
96+
7797
// Register sends a request to the supernode to register itself as a peer
7898
// and create downloading task.
7999
func (api *supernodeAPI) Register(node string, req *types.RegisterRequest) (

dfget/core/api/supernode_api_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ func init() {
5656

5757
// ----------------------------------------------------------------------------
5858
// unit tests for SupernodeAPI
59+
func (s *SupernodeAPITestSuite) TestSupernodeAPI_Ping(c *check.C) {
60+
r, e := s.api.Ping(localhost)
61+
c.Check(r, check.Equals, "")
62+
c.Check(e.Error(), check.Equals, "0:")
63+
}
5964

6065
func (s *SupernodeAPITestSuite) TestSupernodeAPI_Register(c *check.C) {
6166
s.mock.PostJSONFunc = s.mock.CreatePostJSONFunc(0, nil, nil)

dfget/core/core.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,23 @@ func checkConnectSupernode(locator locator.SupernodeLocator) (localIP string) {
293293
if locator == nil {
294294
return ""
295295
}
296+
supernodeApi := api.NewSupernodeAPI()
296297
for _, group := range locator.All() {
297298
for _, n := range group.Nodes {
299+
// step 1. query supernode api get request ip, check if request ip in local eth IPs
300+
if localIP, e = supernodeApi.Ping(n.String()); e == nil {
301+
logrus.Infof("Connect to supernode get self ip:%s", localIP)
302+
if localIPs, err := netutils.GetAllIPs(); err == nil {
303+
for _, lip := range localIPs {
304+
if localIP == lip {
305+
return localIP
306+
}
307+
}
308+
}
309+
}else {
310+
logrus.Warnf("Connect to supernode:%s error: %v", n, e)
311+
}
312+
// step 2. if request ip not in eth ips, it might behind NAT, try use TCP conn to get localIP
298313
if localIP, e = httputils.CheckConnect(n.IP, n.Port, 1000); e == nil {
299314
return localIP
300315
}

dfget/core/helper/test_helper.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ func CreateRandomString(cap int) string {
103103
// ----------------------------------------------------------------------------
104104
// MockSupernodeAPI
105105

106+
type PingFuncType func(ip string) (string, error)
107+
106108
// RegisterFuncType function type of SupernodeAPI#Register
107109
type RegisterFuncType func(ip string, req *types.RegisterRequest) (*types.RegisterResponse, error)
108110

@@ -123,6 +125,7 @@ type ReportMetricsFuncType func(node string, req *api_types.TaskMetricsRequest)
123125

124126
// MockSupernodeAPI mocks the SupernodeAPI.
125127
type MockSupernodeAPI struct {
128+
PingFunc PingFuncType
126129
RegisterFunc RegisterFuncType
127130
PullFunc PullFuncType
128131
ReportFunc ReportFuncType
@@ -133,6 +136,14 @@ type MockSupernodeAPI struct {
133136

134137
var _ api.SupernodeAPI = &MockSupernodeAPI{}
135138

139+
// Ping implements SupernodeAPI#Ping.
140+
func (m *MockSupernodeAPI) Ping(node string) (reqIP string, err error) {
141+
if m.PingFunc != nil {
142+
return m.PingFunc(node)
143+
}
144+
return "127.0.0.1", nil
145+
}
146+
136147
// Register implements SupernodeAPI#Register.
137148
func (m *MockSupernodeAPI) Register(ip string, req *types.RegisterRequest) (
138149
*types.RegisterResponse, error) {

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ require (
2929
github.com/magiconair/properties v1.8.1 // indirect
3030
github.com/mailru/easyjson v0.0.0-20170902151237-2a92e673c9a6 // indirect
3131
github.com/mitchellh/mapstructure v1.1.2
32+
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
3233
github.com/openacid/low v0.1.10
3334
github.com/pborman/uuid v0.0.0-20180122190007-c65b2f87fee3
3435
github.com/pkg/errors v0.8.0
@@ -45,6 +46,7 @@ require (
4546
github.com/willf/bitset v0.0.0-20190228212526-18bd95f470f9
4647
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 // indirect
4748
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 // indirect
49+
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
4850
gopkg.in/gcfg.v1 v1.2.3
4951
gopkg.in/mgo.v2 v2.0.0-20160818020120-3f83fa500528 // indirect
5052
gopkg.in/natefinch/lumberjack.v2 v2.0.0

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5
118118
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
119119
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
120120
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
121+
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
122+
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
121123
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
122124
github.com/openacid/errors v0.8.1/go.mod h1:GUQEJJOJE3W9skHm8E8Y4phdl2LLEN8iD7c5gcGgdx0=
123125
github.com/openacid/low v0.1.10 h1:rKpmB5CHtKoPq9tFiqUvRk8vtWaPympL2D2dNfw3PvI=
@@ -236,6 +238,8 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
236238
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
237239
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
238240
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
241+
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
242+
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
239243
gopkg.in/gcfg.v1 v1.2.3 h1:m8OOJ4ccYHnx2f4gQwpno8nAX5OGOh7RLaaz0pj3Ogs=
240244
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
241245
gopkg.in/mgo.v2 v2.0.0-20160818020120-3f83fa500528 h1:/saqWwm73dLmuzbNhe92F0QsZ/KiFND+esHco2v1hiY=

pkg/httputils/http_util_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,16 @@ func (s *HTTPUtilTestSuite) TestCheckConnect(c *check.C) {
154154
c.Assert(e, check.NotNil)
155155
}
156156

157+
func (s *HTTPUtilTestSuite) TestCheckSuperNodeConnect(c *check.C) {
158+
ip, e := CheckSuperNodeConnect("127.0.0.1", s.port, 0)
159+
c.Assert(e, check.IsNil)
160+
c.Assert(ip, check.Equals, "127.0.0.1")
161+
162+
// Test IPv6
163+
_, e = CheckSuperNodeConnect("[::1]", s.port, 0)
164+
c.Assert(e, check.NotNil)
165+
}
166+
157167
func (s *HTTPUtilTestSuite) TestGetRangeSE(c *check.C) {
158168
var cases = []struct {
159169
rangeHTTPHeader string

supernode/server/system_bridge.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,15 @@ package server
1919
import (
2020
"context"
2121
"net/http"
22+
"strings"
2223
)
2324

2425
func (s *Server) ping(context context.Context, rw http.ResponseWriter, req *http.Request) (err error) {
26+
remoteIP := ""
27+
if idx := strings.LastIndexByte(req.RemoteAddr, ':'); idx >= 0 {
28+
remoteIP = req.RemoteAddr[:idx]
29+
}
2530
rw.WriteHeader(http.StatusOK)
26-
_, err = rw.Write([]byte{'O', 'K'})
31+
_, err = rw.Write([]byte(remoteIP))
2732
return err
2833
}

0 commit comments

Comments
 (0)