Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
G
go-ipfs
概览
概览
详情
活动
周期分析
版本库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
jihao
go-ipfs
Commits
334f9d21
提交
334f9d21
authored
1月 19, 2015
作者:
Juan Batiz-Benet
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
p2p/net/conn: use reuseport
上级
911a3c90
隐藏空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
91 行增加
和
27 行删除
+91
-27
dial.go
p2p/net/conn/dial.go
+76
-26
listen.go
p2p/net/conn/listen.go
+15
-1
没有找到文件。
p2p/net/conn/dial.go
浏览文件 @
334f9d21
...
...
@@ -2,11 +2,14 @@ package conn
import
(
"fmt"
"math/rand"
"net"
"strings"
context
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
ma
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
manet
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
reuseport
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-reuseport"
peer
"github.com/jbenet/go-ipfs/p2p/peer"
debugerror
"github.com/jbenet/go-ipfs/util/debugerror"
...
...
@@ -22,32 +25,7 @@ func (d *Dialer) String() string {
// Example: d.DialAddr(ctx, peer.Addresses()[0], peer)
func
(
d
*
Dialer
)
Dial
(
ctx
context
.
Context
,
raddr
ma
.
Multiaddr
,
remote
peer
.
ID
)
(
Conn
,
error
)
{
_
,
_
,
err
:=
manet
.
DialArgs
(
raddr
)
if
err
!=
nil
{
return
nil
,
err
}
if
strings
.
HasPrefix
(
raddr
.
String
(),
"/ip4/0.0.0.0"
)
{
return
nil
,
debugerror
.
Errorf
(
"Attempted to connect to zero address: %s"
,
raddr
)
}
if
len
(
d
.
LocalAddrs
)
>
0
{
laddrs
:=
manet
.
AddrMatch
(
raddr
,
d
.
LocalAddrs
)
if
len
(
laddrs
)
<
1
{
return
nil
,
debugerror
.
Errorf
(
"No local address matches %s %s"
,
raddr
,
d
.
LocalAddrs
)
}
// TODO pick with a good heuristic
// we use a random one for now to prevent bad addresses from making nodes unreachable
// with a random selection, multiple tries may work.
// laddr := laddrs[rand.Intn(len(laddrs))]
// TODO: try to get reusing addr/ports to work.
// d.Dialer.LocalAddr = laddr
}
log
.
Debugf
(
"%s dialing %s %s"
,
d
.
LocalPeer
,
remote
,
raddr
)
maconn
,
err
:=
d
.
Dialer
.
Dial
(
raddr
)
maconn
,
err
:=
d
.
rawConnDial
(
ctx
,
raddr
,
remote
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -92,6 +70,78 @@ func (d *Dialer) Dial(ctx context.Context, raddr ma.Multiaddr, remote peer.ID) (
return
connOut
,
errOut
}
// rawConnDial dials the underlying net.Conn + manet.Conns
func
(
d
*
Dialer
)
rawConnDial
(
ctx
context
.
Context
,
raddr
ma
.
Multiaddr
,
remote
peer
.
ID
)
(
manet
.
Conn
,
error
)
{
// before doing anything, check we're going to be able to dial.
// we may not support the given address.
_
,
_
,
err
:=
manet
.
DialArgs
(
raddr
)
if
err
!=
nil
{
return
nil
,
err
}
if
strings
.
HasPrefix
(
raddr
.
String
(),
"/ip4/0.0.0.0"
)
{
return
nil
,
debugerror
.
Errorf
(
"Attempted to connect to zero address: %s"
,
raddr
)
}
// get local addr to use.
laddr
:=
pickLocalAddr
(
d
.
LocalAddrs
,
raddr
)
log
.
Debugf
(
"%s dialing %s -- %s --> %s"
,
d
.
LocalPeer
,
remote
,
laddr
,
raddr
)
if
laddr
!=
nil
{
// dial using reuseport.Dialer, because we're probably reusing addrs.
// this is optimistic, as the reuseDial may fail to bind the port.
log
.
Debugf
(
"trying to reuse: %s"
,
laddr
)
if
nconn
,
err
:=
d
.
reuseDial
(
laddr
,
raddr
);
err
==
nil
{
// if it worked, wrap the raw net.Conn with our manet.Conn
log
.
Debugf
(
"reuse worked! %s %s %s"
,
laddr
,
nconn
.
RemoteAddr
(),
nconn
)
return
manet
.
WrapNetConn
(
nconn
)
}
// if not, we fall back to regular Dial without a local addr specified.
}
// no local addr, or failed to reuse. just dial straight with a new port.
return
d
.
Dialer
.
Dial
(
raddr
)
}
func
(
d
*
Dialer
)
reuseDial
(
laddr
,
raddr
ma
.
Multiaddr
)
(
net
.
Conn
,
error
)
{
// give reuse.Dialer the manet.Dialer's Dialer.
// (wow, Dialer should've so been an interface...)
rd
:=
reuseport
.
Dialer
{
d
.
Dialer
.
Dialer
}
// get the local net.Addr manually
var
err
error
rd
.
D
.
LocalAddr
,
err
=
manet
.
ToNetAddr
(
laddr
)
if
err
!=
nil
{
return
nil
,
err
}
// get the raddr dial args for rd.dial
network
,
netraddr
,
err
:=
manet
.
DialArgs
(
raddr
)
if
err
!=
nil
{
return
nil
,
err
}
// rd.Dial gets us a net.Conn with SO_REUSEPORT and SO_REUSEADDR set.
return
rd
.
Dial
(
network
,
netraddr
)
}
func
pickLocalAddr
(
laddrs
[]
ma
.
Multiaddr
,
raddr
ma
.
Multiaddr
)
(
laddr
ma
.
Multiaddr
)
{
if
len
(
laddrs
)
<
1
{
return
nil
}
laddrs
=
manet
.
AddrMatch
(
raddr
,
laddrs
)
if
len
(
laddrs
)
<
1
{
return
nil
}
// TODO pick with a good heuristic
// we use a random one for now to prevent bad addresses from making nodes unreachable
// with a random selection, multiple tries may work.
return
laddrs
[
rand
.
Intn
(
len
(
laddrs
))]
}
// MultiaddrProtocolsMatch returns whether two multiaddrs match in protocol stacks.
func
MultiaddrProtocolsMatch
(
a
,
b
ma
.
Multiaddr
)
bool
{
ap
:=
a
.
Protocols
()
...
...
p2p/net/conn/listen.go
浏览文件 @
334f9d21
...
...
@@ -9,7 +9,9 @@ import (
ctxgroup
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-ctxgroup"
ma
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
manet
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
reuseport
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-reuseport"
tec
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-temp-err-catcher"
ic
"github.com/jbenet/go-ipfs/p2p/crypto"
peer
"github.com/jbenet/go-ipfs/p2p/peer"
)
...
...
@@ -123,11 +125,23 @@ func (l *listener) Loggable() map[string]interface{} {
// Listen listens on the particular multiaddr, with given peer and peerstore.
func
Listen
(
ctx
context
.
Context
,
addr
ma
.
Multiaddr
,
local
peer
.
ID
,
sk
ic
.
PrivKey
)
(
Listener
,
error
)
{
ml
,
err
:=
manet
.
Listen
(
addr
)
network
,
naddr
,
err
:=
manet
.
DialArgs
(
addr
)
if
err
!=
nil
{
return
nil
,
err
}
// _ := reuseport.Listen
// ml, err := manet.Listen(addr)
nl
,
err
:=
reuseport
.
Listen
(
network
,
naddr
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"Failed to listen on %s: %s"
,
addr
,
err
)
}
ml
,
err
:=
manet
.
WrapNetListener
(
nl
)
if
err
!=
nil
{
return
nil
,
err
}
l
:=
&
listener
{
Listener
:
ml
,
local
:
local
,
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论