Comments (12)
I found the previous issue at https://bitbucket.org/python3ldap/python3-ldap/issue/42/doesnt-fall-back-to-ipv4-connection-if - Unfortunately the link is broken, however I still have the emails.
Possibly this should be working, will investigate.
from ldap3.
Quick summary of issues I found, before I run out of time:
In core/server.py
, candidate_addresses()
:
if self.mode == IP_SYSTEM_DEFAULT:
candidates = addresses
Seems better, as otherwise it will only look at the first address.
In strategy/base.py
, open()
, catching all exceptions hides the real error, suspect we only need to catch LDAPSocketOpenError
exception here.
In strategy/base.py, _open_socket()
, we try connecting to self.connection.server.address_info[0][4]
, which is incorrect (it seems to always return the first address in the list for every attempt), we should be trying to connect to address[4]
(If I understand correctly).
This function call to self.connection.socket.connect
returns the following exception from socket.py
in Python, which I am still trying to understand, particularly as it seems to work on the first try with the same parameters:
TypeError: getsockaddrarg() takes exactly 2 parameters (4 given)
Will continue to investigate after my meeting.
from ldap3.
I think I can understand the TypeError
now, the problem is the socket was created for the IPv4 address, but given the IPv6 address. Here is a complete patch against 0.9.8.2 which appears to work for me:
diff -ruN ldap3-0.9.8.2.bak/ldap3/core/server.py ldap3-0.9.8.2/ldap3/core/server.py
--- ldap3-0.9.8.2.bak/ldap3/core/server.py 2015-03-19 08:13:40.000000000 +1100
+++ ldap3-0.9.8.2/ldap3/core/server.py 2015-05-01 13:22:34.445492381 +1000
@@ -417,7 +417,7 @@
candidates = []
if addresses:
if self.mode == IP_SYSTEM_DEFAULT:
- candidates.append(addresses[0])
+ candidates = addresses
elif self.mode == IP_V4_ONLY:
candidates = [address for address in addresses if address[0] == socket.AF_INET and (address[5] or address[5] is None)]
elif self.mode == IP_V6_ONLY:
diff -ruN ldap3-0.9.8.2.bak/ldap3/strategy/base.py ldap3-0.9.8.2/ldap3/strategy/base.py
--- ldap3-0.9.8.2.bak/ldap3/strategy/base.py 2015-04-04 06:01:54.000000000 +1100
+++ ldap3-0.9.8.2/ldap3/strategy/base.py 2015-05-01 13:23:17.420491693 +1000
@@ -101,7 +101,7 @@
self.connection.server.current_address = candidate_address
self.connection.server.update_availability(candidate_address, True)
break
- except Exception:
+ except LDAPSocketOpenError:
self.connection.server.update_availability(candidate_address, False)
exception_history.append((datetime.now(), exc_info()[0], exc_info()[1], candidate_address[4]))
@@ -159,7 +159,7 @@
try:
if self.connection.server.connect_timeout:
self.connection.socket.settimeout(self.connection.server.connect_timeout)
- self.connection.socket.connect(self.connection.server.address_info[0][4])
+ self.connection.socket.connect(address[4])
if self.connection.server.connect_timeout:
self.connection.socket.settimeout(None) # disable socket timeout - socket is in blocking mode
except socket.error as e:
from ldap3.
Thanks Brian,
your help is much needed because I have limited access to a IPv6 network.
Before applying your fix can you try to set the connection "mode" attribute to ldap3.IP_V4_PREFERRED ? This should try IP_V4 before of IPv6.
The IP_SYSTEM_DEFAULT option just takes the first address returned by the operating system, regardless of its "nature" (ipv4 or ipv6). The "mode" options are:
- IP_SYSTEM_DEFAULT (as mentioned before uses only the first address returned by the OS)
- IP_V4_ONLY (uses only ipv4 address)
- IP_V6_ONLY (uses only ipv6 address)
- IP_V4_PREFERRED (tries all ipv4 addresses then ipv6)
- IP_V6_PREFERRED (tries all ipv6 addresses then ipv4)
If this works as intended I could change the default "mode" from IP_SYSTEM_DEFAULT to IP_V4_PREFERRED (that sounds reasonable to me).
Let me know if this solves your problem, else I will investigate more,
Giovanni
from ldap3.
Thanks for your feedback.
I was wondering about this, however thought that IP_SYSTEM_DEFAULT should use the addresses returned in the same order as the OS. I don't feel very strongly about this however, if you feel it should be just the first address, that is fine with me.
The other parts of the patch are still required however.
Also, if should be possible to test this without an IPv6 connection. On my Debian computers, localhost is defined in /etc/hosts as:
127.0.0.1 localhost
::1 localhost
So just trying to connect to localhost
is enough to test this out. Especially if slapd only listens on ipv4 (seems to happen by default on my test suite - I haven't investigated why).
from ldap3.
IP_SYSTEM_DEFAULT means that you get the IP returned by the system, only the first one. This was the original getaddressinfo behaviour before I added the "dual stack" modes. I think this is the most compatible with all version of OS where at least one IP is returned.
Probably I could change the library default from IP_SYSTEM_DEFAULT to IP_V4_PREFERRED.
I will try to replicate the issue on a debian box with openldap.
from ldap3.
I would suggest IP_V6_PREFERRED
be the default, as this is matches what is the defacto standard for almost every other dual stack TCP client.
from ldap3.
Sorry for being late, next release will have IP_V6_PREFERRED as default. I'm also working on extensive logging in the library, so I can check their address problem.
from ldap3.
HI, can you check version 0.9.8.4 in dev? It should fix the problem.
Bye,
Giovanni
from ldap3.
Under Python2 my tests seem to pass, perfectly.
Under Python3 however... Oh wait, I didn't install the package under Python3. So no surprise that didn't work.
So far. Does look a lot better... Thanks
from ldap3.
Thanks Brian, I will release it soon. And thanks for all the testing you're doing. It's very helpful to me.
Bye,
Giovanni
----- Messaggio originale -----
Da: "Brian May" [email protected]
Inviato: 18/05/2015 02:43
A: "cannatag/ldap3" [email protected]
Cc: "Giovanni Cannata" [email protected]
Oggetto: Re: [ldap3] connection fails to fall back to ipv4 if ipv6 fails (#46)
Under Python2 my tests seem to pass, perfectly.
Under Python3 however... Oh wait, I didn't install the package under Python3. So no surprise that didn't work.
So far. Does look a lot better... Thanks
—
Reply to this email directly or view it on GitHub.
from ldap3.
0.9.8.4 released.
bye,
Giovanni
from ldap3.
Related Issues (20)
- serverPool and choices
- ldap3/core/tls.py:317: DeprecationWarning: ssl.match_hostname() is deprecated
- property can be recognized as operational if class was defined with property alias usage
- Error 'invalidCredentials' when attempting SASL+DIGEST_MD5 auth HOT 5
- RFC 2831 not well implemented, causing SASL with DIGEST-MD5 not working with every username / password on Active Directory
- Slow query to AD HOT 3
- SCRAM-SHA-1(-PLUS) + SCRAM-SHA-256(-PLUS) + SCRAM-SHA-512(-PLUS) + SCRAM-SHA3-512(-PLUS) supports
- RFC6331: Moving DIGEST-MD5 to Historic
- RFC 9266: Channel Bindings for TLS 1.3 support HOT 2
- How to get ldap server error message when commiting changes via abstract layer ? HOT 1
- Connection binding times out very late if server names won't resolve
- Seemingly unique issue with AD modifications HOT 1
- Does this library actually end up working reliably with Active Directory? HOT 5
- Controls not working with mock sync?
- Add a way to send an empty AttributeSelection in SearchRequest to request all attributes
- Parentheses in search filter are not properly escaped.
- Missing lockoutTime attribute
- malformed schema definition against ldap.js
- reader search_paged not returning results - What am I doing wrong? HOT 3
- Documentation for adding an object from scratch in abstract mode
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ldap3.