One of the client is the “host” (no game server at all?). If the host is disconnected, the clients automatically select the new host. One of the decision parameters is that which client has has the fastest connection
The host authorizes the most important events (to prevent cheating)
The lag is compensated by:
Dividing events into two parts. The first part is done immediately (e.g. the initial arm movement ) to give immediate response on the local client. The second part (e.g. to throw a grenade) is done after authorization from the host.
Changing the game mechanics on the host when it receives the event. E.g. activating a shield usually takes a small time before the shield is ready. When a host get the shield activation event request from the client, it substracts the lag from the activation time on host to be able to send authorization faster back to the client.