Skip to content

Commit 53aedcc

Browse files
committed
check self connect
1 parent 587569d commit 53aedcc

3 files changed

Lines changed: 73 additions & 14 deletions

File tree

src/brynet/net/Connector.cpp

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ namespace brynet { namespace net {
153153

154154
const sock fd = *(sock*)p;
155155
totalFds.insert(fd);
156-
if (isConnectSuccess(fd, false))
156+
if (isConnectSuccess(fd, false) && !brynet::net::base::IsSelfConnect(fd))
157157
{
158158
successFds.insert(fd);
159159
}
@@ -240,9 +240,9 @@ namespace brynet { namespace net {
240240
sock clientfd = INVALID_SOCKET;
241241

242242
#if defined PLATFORM_WINDOWS
243-
const int check_error = WSAEWOULDBLOCK;
243+
const int ExpectedError = WSAEWOULDBLOCK;
244244
#else
245-
const int check_error = EINPROGRESS;
245+
const int ExpectedError = EINPROGRESS;
246246
#endif
247247
int n = 0;
248248

@@ -262,16 +262,20 @@ namespace brynet { namespace net {
262262
n = connect(clientfd, (struct sockaddr*)&server_addr, sizeof(struct sockaddr));
263263
if (n == 0)
264264
{
265-
goto SUCCESS;
265+
if (brynet::net::base::IsSelfConnect(clientfd))
266+
{
267+
goto FAILED;
268+
}
269+
else
270+
{
271+
goto SUCCESS;
272+
}
266273
}
267-
268-
if (check_error != sErrno)
274+
else if (sErrno != ExpectedError)
269275
{
270-
brynet::net::base::SocketClose(clientfd);
271-
clientfd = INVALID_SOCKET;
272276
goto FAILED;
273277
}
274-
278+
else
275279
{
276280
ConnectingInfo ci;
277281
ci.startConnectTime = std::chrono::steady_clock::now();
@@ -281,8 +285,9 @@ namespace brynet { namespace net {
281285

282286
mConnectingInfos[clientfd] = ci;
283287
ox_fdset_add(mFDSet.get(), clientfd, WriteCheck);
288+
289+
return;
284290
}
285-
return;
286291

287292
SUCCESS:
288293
if (addr.getSuccessCB() != nullptr)
@@ -292,6 +297,11 @@ namespace brynet { namespace net {
292297
return;
293298

294299
FAILED:
300+
if (clientfd != INVALID_SOCKET)
301+
{
302+
brynet::net::base::SocketClose(clientfd);
303+
clientfd = INVALID_SOCKET;
304+
}
295305
if (addr.getFailedCB() != nullptr)
296306
{
297307
addr.getFailedCB()();

src/brynet/net/SocketLibFunction.cpp

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ namespace brynet { namespace net { namespace base {
139139
{
140140
InitSocket();
141141

142-
struct sockaddr_in ip4Addr = { 0 };
142+
struct sockaddr_in ip4Addr = { 0 };
143143
struct sockaddr_in6 ip6Addr = { 0 };
144144
struct sockaddr_in* paddr = &ip4Addr;
145145
int addrLen = sizeof(ip4Addr);
@@ -202,7 +202,7 @@ namespace brynet { namespace net { namespace base {
202202
#endif
203203
}
204204

205-
static std::string get_ip_str(const struct sockaddr *sa)
205+
static std::string getIPString(const struct sockaddr *sa)
206206
{
207207
char tmp[INET6_ADDRSTRLEN] = { 0 };
208208
switch (sa->sa_family)
@@ -229,14 +229,14 @@ namespace brynet { namespace net { namespace base {
229229
int namelen = sizeof(name);
230230
if (getpeername(fd, (struct sockaddr*)&name, &namelen) == 0)
231231
{
232-
return get_ip_str(&name);
232+
return getIPString(&name);
233233
}
234234
#else
235235
struct sockaddr_in name;
236236
socklen_t namelen = sizeof(name);
237237
if (getpeername(fd, (struct sockaddr*)&name, &namelen) == 0)
238238
{
239-
return get_ip_str((const struct sockaddr*)&name);
239+
return getIPString((const struct sockaddr*)&name);
240240
}
241241
#endif
242242

@@ -266,4 +266,52 @@ namespace brynet { namespace net { namespace base {
266266
return socket(af, type, protocol);
267267
}
268268

269+
static struct sockaddr_in6 getLocalAddr(sock sockfd)
270+
{
271+
struct sockaddr_in6 localaddr;
272+
memset(&localaddr, 0, sizeof localaddr);
273+
socklen_t addrlen = static_cast<socklen_t>(sizeof localaddr);
274+
if (::getsockname(sockfd, (struct sockaddr*)(&localaddr), &addrlen) < 0)
275+
{
276+
return localaddr;
277+
}
278+
return localaddr;
279+
}
280+
281+
static struct sockaddr_in6 getPeerAddr(sock sockfd)
282+
{
283+
struct sockaddr_in6 peeraddr;
284+
memset(&peeraddr, 0, sizeof peeraddr);
285+
socklen_t addrlen = static_cast<socklen_t>(sizeof peeraddr);
286+
if (::getpeername(sockfd, (struct sockaddr*)(&peeraddr), &addrlen) < 0)
287+
{
288+
return peeraddr;
289+
}
290+
return peeraddr;
291+
}
292+
293+
/* copy from muduo */
294+
bool IsSelfConnect(sock fd)
295+
{
296+
struct sockaddr_in6 localaddr = getLocalAddr(fd);
297+
struct sockaddr_in6 peeraddr = getPeerAddr(fd);
298+
299+
if (localaddr.sin6_family == AF_INET)
300+
{
301+
const struct sockaddr_in* laddr4 = reinterpret_cast<struct sockaddr_in*>(&localaddr);
302+
const struct sockaddr_in* raddr4 = reinterpret_cast<struct sockaddr_in*>(&peeraddr);
303+
return laddr4->sin_port == raddr4->sin_port
304+
&& laddr4->sin_addr.s_addr == raddr4->sin_addr.s_addr;
305+
}
306+
else if (localaddr.sin6_family == AF_INET6)
307+
{
308+
return localaddr.sin6_port == peeraddr.sin6_port
309+
&& memcmp(&localaddr.sin6_addr, &peeraddr.sin6_addr, sizeof localaddr.sin6_addr) == 0;
310+
}
311+
else
312+
{
313+
return false;
314+
}
315+
}
316+
269317
} } }

src/brynet/net/SocketLibFunction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,6 @@ namespace brynet { namespace net { namespace base {
2222
int SocketSend(sock fd, const char* buffer, int len);
2323
sock Accept(sock listenSocket, struct sockaddr* addr, socklen_t* addrLen);
2424
sock SocketCreate(int af, int type, int protocol);
25+
bool IsSelfConnect(sock fd);
2526

2627
} } }

0 commit comments

Comments
 (0)