Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eldap:search may receive previous call result after a receive timeout #8689

Closed
zmstone opened this issue Jul 25, 2024 · 1 comment
Closed
Labels
bug Issue is reported as a bug

Comments

@zmstone
Copy link
Contributor

zmstone commented Jul 25, 2024

Describe the bug

First of all, like other functions in eldap module, collect_search_responses should probably also have a guard Msg#'LDAPMessage'.messageID =:= ID

otp/lib/eldap/src/eldap.erl

Lines 1254 to 1255 in 64fcd87

collect_search_responses(Data, S, ID, {ok,Msg}, Acc, Ref)
when is_record(Msg,'LDAPMessage') ->

Adding the guard will cause the search call to return {error, ..}, however it may not solve the practical issue.

If the gen_tcp:recv call times out, the next call may receive the previous response.

I have tested it with openldap 2.5.16 in a docker container.

To Reproduce
Steps to reproduce the behavior.

  • Start openldap server in docker. For reference: https://github.com/zmstone/docker-openldap/blob/main/Dockerfile
  • Start eldap to connect the server
  • Call eldap:search to verify that the server should return a successful match, but NOT noSuchObject
  • Find the source port of the connection. e.g. netstat -npt | grep 368 (368 being the ldap server listener port)
  • Add a iptables rule to drop all packets from the source port: sudo iptables -A OUTPUT -p tcp --sport 57690 -j DROP
  • Call eldap:search to send a search request, this call is meant to timeout hence making eldap to bump message ID
  • Delete the iptables rule to resume e.g. sudo iptables -D OUTPUT -p tcp --sport 57690 -j DROP
  • Repeat to call eldap:search to search for an non-existing object to receive the result for the previous call, this time, we expect it to be noSuchObject but it's actually returned the response of the previous search.
  • In Erlang shell, try to get the socket from eldap process, in my case, its #Port<0.19>, and receive data from it, observe something like below (in normal cases, it should timeout)
> gen_tcp:recv(#Port<0.19>,0,1000).
{ok,[48,39,2,1,27,101,34,10,1,32,4,27,111,117,61,116...]}

Expected behavior

eldap should reconnect or exit the process.

or let caller know it should reconnect.
EDIT: it returns {error,{gen_tcp_error,timeout}}

Affected versions

I tested it on Erlang/OTP 26.2.5

Additional context

I have not tried to test slow server response to cause the timeout, instead, I used iptables to simulate network issue.
The query reached the server after the iptables rule is dropped.

@zmstone zmstone added the bug Issue is reported as a bug label Jul 25, 2024
@zmstone
Copy link
Contributor Author

zmstone commented Jul 25, 2024

It seems all errors, including socket closed errors are returned to the caller to handle, but the process does not reconnect neither does it exit.

@zmstone zmstone closed this as completed Jul 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue is reported as a bug
Projects
None yet
Development

No branches or pull requests

1 participant