| 153 | pass |
| 154 | |
| 155 | def getConnection(self, ip=None, port=None, peer_id=None, create=True, site=None, is_tracker_connection=False): |
| 156 | ip_type = helper.getIpType(ip) |
| 157 | has_per_site_onion = (ip.endswith(".onion") or self.port_opened.get(ip_type, None) == False) and self.tor_manager.start_onions and site |
| 158 | if has_per_site_onion: # Site-unique connection for Tor |
| 159 | if ip.endswith(".onion"): |
| 160 | site_onion = self.tor_manager.getOnion(site.address) |
| 161 | else: |
| 162 | site_onion = self.tor_manager.getOnion("global") |
| 163 | key = ip + site_onion |
| 164 | else: |
| 165 | key = ip |
| 166 | |
| 167 | # Find connection by ip |
| 168 | if key in self.ips: |
| 169 | connection = self.ips[key] |
| 170 | if not peer_id or connection.handshake.get("peer_id") == peer_id: # Filter by peer_id |
| 171 | if not connection.connected and create: |
| 172 | succ = connection.event_connected.get() # Wait for connection |
| 173 | if not succ: |
| 174 | raise Exception("Connection event return error") |
| 175 | return connection |
| 176 | |
| 177 | # Recover from connection pool |
| 178 | for connection in self.connections: |
| 179 | if connection.ip == ip: |
| 180 | if peer_id and connection.handshake.get("peer_id") != peer_id: # Does not match |
| 181 | continue |
| 182 | if ip.endswith(".onion") and self.tor_manager.start_onions and ip.replace(".onion", "") != connection.target_onion: |
| 183 | # For different site |
| 184 | continue |
| 185 | if not connection.connected and create: |
| 186 | succ = connection.event_connected.get() # Wait for connection |
| 187 | if not succ: |
| 188 | raise Exception("Connection event return error") |
| 189 | return connection |
| 190 | |
| 191 | # No connection found |
| 192 | if create and not config.offline: # Allow to create new connection if not found |
| 193 | if port == 0: |
| 194 | raise Exception("This peer is not connectable") |
| 195 | |
| 196 | if (ip, port) in self.peer_blacklist and not is_tracker_connection: |
| 197 | raise Exception("This peer is blacklisted") |
| 198 | |
| 199 | try: |
| 200 | if has_per_site_onion: # Lock connection to site |
| 201 | connection = Connection(self, ip, port, target_onion=site_onion, is_tracker_connection=is_tracker_connection) |
| 202 | else: |
| 203 | connection = Connection(self, ip, port, is_tracker_connection=is_tracker_connection) |
| 204 | self.num_outgoing += 1 |
| 205 | self.ips[key] = connection |
| 206 | self.connections.append(connection) |
| 207 | connection.log("Connecting... (site: %s)" % site) |
| 208 | succ = connection.connect() |
| 209 | if not succ: |
| 210 | connection.close("Connection event return error") |
| 211 | raise Exception("Connection event return error") |
| 212 | |