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

Discover and expose SFT servers in /calls/config/v2 #1177

Merged
merged 48 commits into from
Jul 31, 2020
Merged

Conversation

jschaul
Copy link
Member

@jschaul jschaul commented Jul 22, 2020

Differences:
- Uses polysemy to expose the lookup itself
- Doesn't order targets, ordering requires randomization, maybe it can be
exposed with some other effect.
Copy link
Contributor

@fisx fisx left a comment

Choose a reason for hiding this comment

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

lots of comments, hopefully not too much noise?

services/brig/src/Brig/Run.hs Outdated Show resolved Hide resolved
libs/dns-srv/src/Wire/Network/DNS/Effect.hs Outdated Show resolved Hide resolved
libs/dns-srv/src/Wire/Network/DNS/Effect.hs Outdated Show resolved Hide resolved
-- You should have received a copy of the GNU Affero General Public License along
-- with this program. If not, see <https://www.gnu.org/licenses/>.

module Wire.Network.DNS.SRV where
Copy link
Contributor

Choose a reason for hiding this comment

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

If I understand correctly, the types here follow the RFC that describes SFT server lookup, or maybe something slightly more general, but more specific than DNS. Could we link that RFC here?

Copy link
Member

Choose a reason for hiding this comment

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

The RFC defines what SRV records are. The dns package interprets an SRV record into a tuple of 4 things, we named them here for it to be easier to comprehend across the code. Not sure if the mention is worth it. We mention the RFC in the ordering function because it might not be as obvious.

libs/dns-srv/src/Wire/Network/DNS/Effect.hs Outdated Show resolved Hide resolved
libs/dns-srv/src/Wire/Network/DNS/SRV.hs Outdated Show resolved Hide resolved
--
-- Taken from http://hackage.haskell.org/package/pontarius-xmpp (BSD3 licence) and refactored.
orderTargets :: [SrvEntry] -> IO [SrvEntry]
orderTargets =
Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, given that we don't depend on this, it makes sense to me to just randomize the order fully, ignoring weight and prio. Should be random, though. It's easy and nicer, even though it shouldn't have an impact with current client implementations.

Copy link
Member

Choose a reason for hiding this comment

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

We kept the function there as it was written for federation and will be useful anyway. But ended up not using it as it doesn't match up with how clients decide which server to connect to.

libs/wire-api/src/Wire/API/Call/TURN.hs Show resolved Hide resolved
services/brig/brig.cabal Outdated Show resolved Hide resolved
services/brig/src/Brig/Run.hs Outdated Show resolved Hide resolved
* Refactor all `List1` to `NonEmpty` in RTCConfiguration
* Integration tests now depend on globally created DNS entries

Pending:
* Unit tests for discovery
* Unit tests for translating an SrvTarget to an SFTServer
* Figure out if we can override the domain used for integration tests
@fisx
Copy link
Contributor

fisx commented Jul 29, 2020

a7820b5

too bad. :( can we do this cnoditionally, with a cabal compiler version check or something?

- Set discovery interval for sft
- Use retryWhileN correctly by looping while discovery is not done
- Do not assert on the order of servers as it doesn't seem to be stable
@akshaymankar
Copy link
Member

too bad. :( can we do this cnoditionally, with a cabal compiler version check or something?

I think we can have a flag for this, but the thing is completely useless right now. Instead, we should just update our alpine image to have ncurses-dev. I have this branch that will help us add it back in future, but it requires a lot of compiling and one of us watching it compile. I will get to it after I am done with this PR, if I have enough time before my vacation. Feel free to take it off my hands though 😄

We can create another effect for this and make the tests faster (and
deterministic), but later.
@akshaymankar akshaymankar changed the title [WIP] SFT SRV Discover and expose SFT servers in calls config endpoint Jul 30, 2020
@akshaymankar akshaymankar changed the title Discover and expose SFT servers in calls config endpoint Discover and expose SFT servers in /calls/config/v2 Jul 30, 2020
@akshaymankar akshaymankar marked this pull request as ready for review July 30, 2020 07:57
Copy link
Contributor

@fisx fisx left a comment

Choose a reason for hiding this comment

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

still haven't read it all, but here is what i have.

Comment on lines +248 to +250
ensureHttpsUrl :: URIRef Absolute -> HttpsUrl
ensureHttpsUrl = HttpsUrl . (uriSchemeL . schemeBSL .~ "https")

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
ensureHttpsUrl :: URIRef Absolute -> HttpsUrl
ensureHttpsUrl = HttpsUrl . (uriSchemeL . schemeBSL .~ "https")
enforceHttpsUrl :: URIRef Absolute -> HttpsUrl
enforceHttpsUrl = HttpsUrl . (uriSchemeL . schemeBSL .~ "https")
mkHttpsUrl :: Host -> Port -> HttpsUrl
mkHttpsUrl = undefined

(no strong opinion about either; the second may lead to nicer code further down this PR.)

Copy link
Member

Choose a reason for hiding this comment

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

mkHttpsUrl is already defined above and it returns Either String HttpsUrl. enforce and ensure have same semantic meaning in my head, so I also don't have much strength in my opinion here.

libs/wire-api/src/Wire/API/Call/Config.hs Outdated Show resolved Hide resolved
services/brig/src/Brig/PolyLog.hs Show resolved Hide resolved

makeSem 'PolyLog

runPolyLog :: Member (Embed IO) r => Log.Logger -> Sem (PolyLog ': r) a -> Sem r a
Copy link
Contributor

Choose a reason for hiding this comment

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

... and shouldn't the logger be provided by the effect, like in the logger mtl class?

Copy link
Member

Choose a reason for hiding this comment

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

How do you mean? This function interprets the effect in terms of IO, I don't think it should create a logger, since there are a bunch of log settings we might want to control from wherever the app is being started.

services/brig/src/Brig/Run.hs Show resolved Hide resolved
services/brig/src/Brig/Run.hs Outdated Show resolved Hide resolved
import Wire.API.Call.Config

tests :: Manager -> Brig -> Opts.Opts -> FilePath -> FilePath -> IO TestTree
tests m b opts turn turnV2 = do
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit-picks: why does this return in IO, and not purely? Also, formatting is not very nice.

Copy link
Member

Choose a reason for hiding this comment

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

I think this is because in some integration tests we do some IO things for all the testGroups and here we just kept it similar to that. I think it is better have the tests functions be an IO everywhere rather than in only some places. But I don't really feel very strongly on this one.

services/brig/test/integration/API/Calling.hs Show resolved Hide resolved
Copy link
Contributor

@fisx fisx left a comment

Choose a reason for hiding this comment

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

two more files to go...

-- You should have received a copy of the GNU Affero General Public License along
-- with this program. If not, see <https://www.gnu.org/licenses/>.

module Brig.Calling where
Copy link
Contributor

Choose a reason for hiding this comment

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

can you make an explicit export list? it (a) should be the default, and (b) may reveal that Discovery doesn't have to have any constructors exported, which would make it harder to violate its invariant.

Copy link
Member

Choose a reason for hiding this comment

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

But I want to use the constructors in the tests. I could always translate it to Maybe in the tests but that would make them cumbersome. I think it is OK to leave it at this as it clearly states the semantics and doesn't come in the way of testing.

services/brig/src/Brig/Calling/API.hs Show resolved Hide resolved
pure $ Public.rtcConfiguration srvs cTTL
pure $ Public.rtcIceServer (uri :| []) u (computeCred sha secret u)
sftSrvEntries <- maybe (pure Nothing) ((fmap discoveryToMaybe) . readIORef . sftServers) mSftEnv
-- According to RFC2782, the SRV Entries are supposed to be tried in order of
Copy link
Contributor

Choose a reason for hiding this comment

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

I would say don't randomize here and add the fact that the list has set semantics to the swagger spec. Saves server resources and is at least clear about this. While we're at it, we might as well remove the randomization above as well.

But I'm not going to insist. Minimizing change is also nice.

Copy link
Member Author

@jschaul jschaul Jul 30, 2020

Choose a reason for hiding this comment

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

Changes here need to be discussed with the AVS team, since they are using these entries on the client side, and the current agreement was (as far as I'm aware - unless there were further discussions on this topic since?) "the list is randomized". We can make changes here in future PRs after a discussion, if a certain logic should happen on the client side.

services/brig/src/Brig/Calling/Internal.hs Outdated Show resolved Hide resolved
}
deriving (Show, Generic)

instance FromJSON SFTOptions where
Copy link
Contributor

Choose a reason for hiding this comment

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

(Wild thought: we should have a couple of strings in the test suite and tests that they parse as server config files.)

recordLogs LogRecorder {..} = interpret $ \(PolyLog lvl msg) ->
modifyIORef' recordedLogs (++ [(lvl, Log.render (Log.renderDefault ", ") msg)])

ignoreLogs :: Sem (PolyLog ': r) a -> Sem r a
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't like the name PolyLog (it's a nice name, but it doesn't point out what it refers to clearly enough for my taste). But we can change it later.

I do like the fact that we're introducing polysemi! :)

Copy link
Member

Choose a reason for hiding this comment

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

I felt like being clever 😄
What would be a better name?

Copy link
Member Author

@jschaul jschaul left a comment

Choose a reason for hiding this comment

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

I started the PR, but didn't do much work, so I can't approve with the button here, so I'll approve this work with a comment: ✔️

pure $ Public.rtcConfiguration srvs cTTL
pure $ Public.rtcIceServer (uri :| []) u (computeCred sha secret u)
sftSrvEntries <- maybe (pure Nothing) ((fmap discoveryToMaybe) . readIORef . sftServers) mSftEnv
-- According to RFC2782, the SRV Entries are supposed to be tried in order of
Copy link
Member Author

@jschaul jschaul Jul 30, 2020

Choose a reason for hiding this comment

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

Changes here need to be discussed with the AVS team, since they are using these entries on the client side, and the current agreement was (as far as I'm aware - unless there were further discussions on this topic since?) "the list is randomized". We can make changes here in future PRs after a discussion, if a certain logic should happen on the client side.

@fisx
Copy link
Contributor

fisx commented Jul 30, 2020

Hey github, why can i not reply to #1177 (comment)?

anyway, what i meant was that this should not take the logger as a function argument, but get it out of a reader effect. we agree that it shouldn't be created on the fly with the wrong parameters. :)

@fisx
Copy link
Contributor

fisx commented Jul 30, 2020

#1177 (comment)

Perhaps we should start writing tests in the production code modules, and merely calling them from /package/tests? Anyway, other issue, other PR, other year.

Copy link
Contributor

@fisx fisx left a comment

Choose a reason for hiding this comment

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

all good! two more comments, but i think nobody will die if you ignore them.

services/brig/test/unit/Test/Brig/Calling.hs Show resolved Hide resolved
services/brig/test/unit/Test/Brig/Calling.hs Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants