@@ -115,45 +115,50 @@ void Peer::received(
115
115
}
116
116
117
117
bool attemptToContact = false ;
118
-
119
- int replaceIdx = ZT_MAX_PEER_NETWORK_PATHS;
120
118
if ((!havePath)&&(RR->node ->shouldUsePathForZeroTierTraffic (tPtr,_id.address (),path->localSocket (),path->address ()))) {
121
119
Mutex::Lock _l (_paths_m);
120
+
121
+ // Paths are redunant if they duplicate an alive path to the same IP or
122
+ // with the same local socket and address family.
123
+ bool redundant = false ;
122
124
for (unsigned int i=0 ;i<ZT_MAX_PEER_NETWORK_PATHS;++i) {
123
125
if (_paths[i].p ) {
124
- // match addr
125
- if ( (_paths[i].p ->alive (now)) && ( ((_paths[i].p ->localSocket () == path->localSocket ())&&(_paths[i].p ->address ().ss_family == path->address ().ss_family )) && (_paths[i].p ->address ().ipsEqual2 (path->address ())) ) ) {
126
- // port
127
- if (_paths[i].p ->address ().port () == path->address ().port ()) {
128
- replaceIdx = i;
129
- break ;
130
- }
126
+ if ( (_paths[i].p ->alive (now)) && ( ((_paths[i].p ->localSocket () == path->localSocket ())&&(_paths[i].p ->address ().ss_family == path->address ().ss_family )) || (_paths[i].p ->address ().ipsEqual2 (path->address ())) ) ) {
127
+ redundant = true ;
128
+ break ;
131
129
}
132
- }
130
+ } else break ;
133
131
}
134
- if (replaceIdx == ZT_MAX_PEER_NETWORK_PATHS) {
132
+
133
+ if (!redundant) {
134
+ unsigned int replacePath = ZT_MAX_PEER_NETWORK_PATHS;
135
+ int replacePathQuality = 0 ;
135
136
for (unsigned int i=0 ;i<ZT_MAX_PEER_NETWORK_PATHS;++i) {
136
- if (!_paths[i].p ) {
137
- replaceIdx = i;
137
+ if (_paths[i].p ) {
138
+ const int q = _paths[i].p ->quality (now);
139
+ if (q > replacePathQuality) {
140
+ replacePathQuality = q;
141
+ replacePath = i;
142
+ }
143
+ } else {
144
+ replacePath = i;
138
145
break ;
139
146
}
140
147
}
141
- }
142
- if (replaceIdx != ZT_MAX_PEER_NETWORK_PATHS) {
143
- if (verb == Packet::VERB_OK) {
144
- RR->t ->peerLearnedNewPath (tPtr,networkId,*this ,path,packetId);
145
- performMultipathStateCheck (now);
146
- if (_bondToPeer) {
147
- _bondToPeer->nominatePath (path, now);
148
+
149
+ if (replacePath != ZT_MAX_PEER_NETWORK_PATHS) {
150
+ if (verb == Packet::VERB_OK) {
151
+ RR->t ->peerLearnedNewPath (tPtr,networkId,*this ,path,packetId);
152
+ _paths[replacePath].lr = now;
153
+ _paths[replacePath].p = path;
154
+ _paths[replacePath].priority = 1 ;
155
+ } else {
156
+ attemptToContact = true ;
148
157
}
149
- _paths[replaceIdx].lr = now;
150
- _paths[replaceIdx].p = path;
151
- _paths[replaceIdx].priority = 1 ;
152
- } else {
153
- attemptToContact = true ;
154
158
}
155
159
}
156
160
}
161
+
157
162
if (attemptToContact) {
158
163
attemptToContactAt (tPtr,path->localSocket (),path->address (),now,true );
159
164
path->sent (now);
0 commit comments