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

coretasks: fix bad WHO tracking endless loop #2091

Merged
merged 1 commit into from
Jun 13, 2021

Conversation

HumorBaby
Copy link
Contributor

Description

who_reqs, which is used to track WHO requests to the server, had flipped
keys/values and was never getting cleared upon RPL_ENDOFWHO.
Eventually, this would lead to an endless loop while the bot tried to
get an unused "querytype" (randint) in order to track WHO replies.

Now, key/values are in a more useful order (channel --map--> querytype).
Also, the unneccessary loop used to ensure unique values for the query type was
removed. A RPL_WHOREPLY includes the channel name in the response, so
confirming that the querytype for a channel matched is sufficient. The same
querytype could even be used for every channel without issue.

Checklist

  • I have read CONTRIBUTING.md
  • I can and do license this contribution under the EFLv2
  • No issues are reported by make qa (runs make quality and make test)
  • I have tested the functionality of the things this change touches

@HumorBaby HumorBaby requested a review from a team June 8, 2021 07:39
@HumorBaby HumorBaby added the Bugfix Generally, PRs that reference (and fix) one or more issue(s) label Jun 8, 2021
sopel/coretasks.py Outdated Show resolved Hide resolved
Exirel
Exirel previously approved these changes Jun 8, 2021
Copy link
Contributor

@Exirel Exirel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch. This should be noted as a successful week of bug hunt!

@HumorBaby HumorBaby force-pushed the fix-send-who-infinite-loop branch from d481569 to a56c0ee Compare June 8, 2021 13:19
@HumorBaby
Copy link
Contributor Author

Sorry, @Exirel, I have to reject your approval.
I added more 🥺…

See commit message for coretask: update proper usage of WHOX querytype.
TLDR; querytype wasn't being used properly. Updated to spec.

Included the update with this PR since it is closely related to the bugfix, and a separate PR would immediately move/remove some of the fix changes. IMO, should be updated eventually, so why not now, eh?
Also, I was extra-:rage: because, had it been used correctly to begin, this fix would not have been necessary.

I'm happy to discuss alternatives to this combo.

@HumorBaby HumorBaby requested a review from Exirel June 8, 2021 14:06
@dgw dgw added this to the 7.1.1 milestone Jun 9, 2021
@dgw dgw dismissed Exirel’s stale review June 9, 2021 01:15

PR has changed significantly (4fc75c1) since review

Copy link
Member

@dgw dgw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm nitpicking. It's my job, no? 😁

Nothing here is part of Sopel's documented API, thankfully. This is probably safe to release as part of 7.1.1, though I wish the "type" of WHO query could be non-numeric. 000 is something other people might already use in their plugins (though I did search GitHub for "sopel who 000" in all indexed Python code and found a total of 10 irrelevant hits—it's probably perfectly fine).

Oh well. Up to now it was possible to get Heisenbugs if the random integer happened to collide with some custom code's WHO requests. Now it'll be consistent, and therefore easier to find/fix.

sopel/coretasks.py Show resolved Hide resolved
sopel/coretasks.py Outdated Show resolved Hide resolved
@HumorBaby
Copy link
Contributor Author

… though I wish the "type" of WHO query could be non-numeric. 000

Wellll actually, nowhere does it "officially" say it has to be numeric (where officially refers to IRCd docs, and not random forums on the interwebz). The pages cited in the comments (and commit message) use numbers in the example and one uses the term "digits" (which I believe hope was meant as characters 🤞)

Looking at the source for IRCd's that implement WHOX (I checked ergo/oregano, InspIRCd, UnderNet's ircu2, Libera.chat's solanum, and freenode's ircd-seven) and they all store querytype as a language-specific string (e.g., char[] what have you). There is no enforcement of numeric querytypes. The only validation+enforment being: if your querytype is longer than three characters, they auto-default to "0" (still string).

… what to do?? "Lmk"?

@dgw
Copy link
Member

dgw commented Jun 10, 2021

Yeah, you read the same Faerion page I did, which is where the "digits" thing came from. What annoys me about WHOX is that there seems to be no real spec to follow…which means we're stuck doing what you did, and what I presume the previous maintainers did: digging through IRCd source code. Not great.

In the absence of such a spec, though, I'd be wary of doing anything that might run afoul of older IRCds' logic. Your checks validate that being numeric isn't required now, but perhaps it was in the past. A counterexample I found is from DareNET's current documentation (snapshot) on WHOX: it specifies "value between 0 and 999".

Seriously, though. We can commiserate over the lack of a formal standard for WHOX all we want, but the endgame is always going to be "leave it as 000; it's fine". 😉

Copy link
Contributor

@Exirel Exirel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as dgw: let's remove that end_who plugin callable.

sopel/coretasks.py Outdated Show resolved Hide resolved
who_reqs, which is used to track WHO requests to the server, had flipped
keys/values and was never getting cleared upon RPL_ENDOFWHO.
Eventually, this would lead to an endless loop while the bot tried to
get an unused "querytype" (randint) in order to track WHO replies.

This unneccessary loop/check to ensure unique values for the query type was
removed. A RPL_WHOREPLY includes the channel name in the response, so
confirming that the querytype for a channel matched is sufficient.

querytype should be unique _per purpose_. So, now a constant querytype
is used for `coretasks` WHO(X) requests.

Notes:
According to [the closest thing to] official specs:
ircv3/ircv3-specifications#81 (comment)
querytypes should be useful to:
> simplify scripting, in example one could pass a certain value in the query
> and have that value "signal" back what is to be done with those replies.

Also see:
https://github.com/quakenet/snircd/blob/17c92003d376c70db674821e92f2880ba1587132/doc/readme.who#L154
https://github.com/quakenet/snircd/blob/17c92003d376c70db674821e92f2880ba1587132/doc/readme.who#L105
@HumorBaby HumorBaby force-pushed the fix-send-who-infinite-loop branch from 4fc75c1 to f11dca5 Compare June 12, 2021 01:18
@HumorBaby
Copy link
Contributor Author

In the absence of such a spec, though, I'd be wary of doing anything that might run afoul of older IRCds' logic. Your checks validate that being numeric isn't required now, but perhaps it was in the past. A counterexample I found is from DareNET's current documentation (snapshot) on WHOX: it specifies "value between 0 and 999".

Seriously, though. We can commiserate over the lack of a formal standard for WHOX all we want, but the endgame is always going to be "leave it as 000; it's fine".

@dgw, based on your reasoning, I have actually decided to change it to "999". Sopel checks for correct querytype as a string match, despite being numeric. So, if an old IRCd casts a querytype with value < 100 to a numeric, it may end up causing false negatives when, for example, "42" != "042".

In other news, I made the rest of the requested changes and squashed the original loop fix + set querytype constant commits.

Copy link
Member

@dgw dgw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉🥳🚀

So, if an old IRCd casts a querytype with value < 100 to a numeric, it may end up causing false negatives when, for example, "42" != "042".

That is a good point! It's no reason to amend the PR, but just so you know how silly I am: I probably would have picked something like "Sopel" encoded to T9 with the vowels removed ("775"), or a common "lucky" number like 777 or 888. 😁

@dgw dgw requested a review from Exirel June 12, 2021 23:40
Copy link
Contributor

@Exirel Exirel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's merge that and publish a 7.1.1 asap.

@dgw dgw merged commit 2348b57 into sopel-irc:master Jun 13, 2021
dgw pushed a commit that referenced this pull request Jun 13, 2021
who_reqs, which is used to track WHO requests to the server, had flipped
keys/values and was never getting cleared upon RPL_ENDOFWHO.
Eventually, this would lead to an endless loop while the bot tried to
get an unused "querytype" (randint) in order to track WHO replies.

This unneccessary loop/check to ensure unique values for the query type was
removed. A RPL_WHOREPLY includes the channel name in the response, so
confirming that the querytype for a channel matched is sufficient.

querytype should be unique _per purpose_. So, now a constant querytype
is used for `coretasks` WHO(X) requests.

Notes:
According to [the closest thing to] official specs:
ircv3/ircv3-specifications#81 (comment)
querytypes should be useful to:
> simplify scripting, in example one could pass a certain value in the query
> and have that value "signal" back what is to be done with those replies.

Also see:
https://github.com/quakenet/snircd/blob/17c92003d376c70db674821e92f2880ba1587132/doc/readme.who#L154
https://github.com/quakenet/snircd/blob/17c92003d376c70db674821e92f2880ba1587132/doc/readme.who#L105

----

Backport to 7.1.1 release of pull request #2091, commit
f11dca5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bugfix Generally, PRs that reference (and fix) one or more issue(s) High Priority
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants