/
peer.go
135 lines (113 loc) · 5.5 KB
/
peer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
* Copyright 2018 The openwallet Authors
* This file is part of the openwallet library.
*
* The openwallet library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The openwallet library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*/
package owtp
import (
"github.com/tidwall/gjson"
"net"
)
const (
DataPacketVersionV1 = 1 //数据包版本v1
CurrentDataPacketVersion = DataPacketVersionV1 //当前的数据包版本
)
//DataPacket 数据包
type DataPacket struct {
/*
本协议传输数据,格式编码采用json。消息接收与发送,都遵循数据包规范定义字段内容。
| 参数名 | 类型 | 示例 | 描述 |
|--------|--------|------------------|-----------------------------------------------------------------------------------|
| r | uint8 | 1 | 传输类型,1:请求,2:响应 |
| v | int64 | 1 | 版本号 |
| m | string | subscribe | 方法名,对应接口方法定义 |
| n | uint32 | 123 | 请求序号。为了保证请求对应响应按序执行,并防御重放攻击,序号可以为随机数,但不可重复。 |
| t | uint32 | 1528520843 | 时间戳。限制请求在特定时间范围内有效,如10分钟。 |
| d | Object | {"foo": "hello"} | 数据主体,请求内容或响应内容。接口方法说明中,主要说明这部分。 |
| s | string | Qwse | [可选]合并[r+m+n+t+d]进行sha256两次ECC签名并base58编码,用于校验数据的一致性和合法性 |
| k | Object | 1b24ac | [可选]协商密码数据包,开启协商密码的必须字段,数据解析查看《3.5.1 协商密码数据包解析》 |
*/
Req uint64 `json:"r"`
Method string `json:"m"`
Nonce uint64 `json:"n" storm:"id"`
Timestamp int64 `json:"t"`
Data interface{} `json:"d"`
Signature string `json:"s"`
SecretData SecretData `json:"k"`
Version int64 `json:"v"`
}
//KeyAgreement 协商密码
type SecretData struct {
PublicKeyInitiator string `json:"pk"` //发起方公钥
TmpPublicKeyInitiator string `json:"tpk"` //发起方临时公钥
EncryptType string `json:"et"` //加密类型
PublicKeyResponder string `json:"pko"` //响应方公钥
TmpPublicKeyResponder string `json:"tpo"` //响应方临时公钥
SB string `json:"sb"` //响应方发送给发起方的校验值
SA string `json:"sa"` //发起方发送给响应方的校验值
S2 string `json:"s2"` //响应方协商密码计算的校验值
}
//NewDataPacket 通过 gjson转为DataPacket
func NewDataPacket(json gjson.Result) *DataPacket {
dp := &DataPacket{}
dp.Req = json.Get("r").Uint()
dp.Method = json.Get("m").String()
dp.Nonce = json.Get("n").Uint()
dp.Timestamp = json.Get("t").Int()
dp.Data = json.Get("d").String()
dp.Signature = json.Get("s").String()
dp.Version = json.Get("v").Int()
dp.SecretData = SecretData{}
dp.SecretData.PublicKeyInitiator = json.Get("k.pk").String()
dp.SecretData.TmpPublicKeyInitiator = json.Get("k.tpk").String()
dp.SecretData.EncryptType = json.Get("k.et").String()
dp.SecretData.PublicKeyResponder = json.Get("k.pko").String()
dp.SecretData.TmpPublicKeyResponder = json.Get("k.tpo").String()
dp.SecretData.SB = json.Get("k.sb").String()
dp.SecretData.SA = json.Get("k.sa").String()
dp.SecretData.S2 = json.Get("k.s2").String()
//兼容旧版本
if json.Get("z").Exists() {
dp.SecretData.SA = json.Get("z").String()
}
return dp
}
type PeerInfo struct {
ID string
Config ConnectConfig
}
type PeerAttribute map[string]interface{}
// Peer 节点
type Peer interface {
/* 公开方法 */
PID() string //节点ID
IsHost() bool //是否主机,我方主动连接的节点
IsConnected() bool //是否已经连接
LocalAddr() net.Addr //本地节点地址
RemoteAddr() net.Addr //远程节点地址
ConnectConfig() ConnectConfig // 返回配置信息
EnableKeyAgreement() bool //EnableKeyAgreement 开启密码协商
/* 内部方法 */
auth() Authorization
setHandler(handler PeerHandler) error //设置节点的服务者
openPipe() error //OpenPipe 打开通道
send(data DataPacket) error //发送请求
close() error //关闭节点
}
// PeerHandler 节点监听器
type PeerHandler interface {
OnPeerOpen(peer Peer) //节点连接成功
OnPeerClose(peer Peer, reason string) //节点关闭
OnPeerNewDataPacketReceived(peer Peer, packet *DataPacket) //节点获取新数据包
GetValueForPeer(peer Peer, key string) interface{}
PutValueForPeer(peer Peer, key string, val interface{}) error
}