You understanding of these systems seems correct. IOnlineSubsystem is our abstraction for supporting what we call “platform services”, like LIVE, PSN, Steam, etc. It handles the bookkeeping necessary to interact with their matchmaking, game advertisement, leaderboards, achievements, etc. When you aren’t associated with any of these services, there is a NULL implementation that may do some basic work, but ultimately just calls the delegates to continue the flow of the existing calls. It saves having to write custom code for when you are not associated with a platform.
The NULL implementation does have some basic LAN beacon advertisement for finding games with other players, but there is no internet wide master server for server browsing.
AGameSession is instantiated on the AGameMode and is the class meant to handle the interactions with the OnlineSubsystem as well as various other “I’m the host” kind of duties. Things like accepting login (possibly checking ban lists and server capacity), spectator permissions, voice chat push to talk requirements, starting/ending a session with the platform.
Hope that helps your understanding.