/* Copyright (c) 2020-2022 The Creators of Simphone

   See the file COPYING.LESSER.txt for copying permission.
*/

#ifndef _NAT_H_
#define _NAT_H_

#include "simtypes.h"

/* check if NAT is waiting for traversal */
simbool nat_check_locked (simclient client);

/* commands for nat_traverse_exec (NAT_CMD_QUIT, NAT_CMD_REQUEST and NAT_CMD_REPLY not allowed) and nat_reverse_exec */
#define NAT_CMD_NONE 0       /* empty string (only for logging) */
#define NAT_CMD_QUIT 1       /* stop the traversal thread */
#define NAT_CMD_START 2      /* locally requested traversal */
#define NAT_CMD_RESTART 3    /* repeat of NAT_CMD_START */
#define NAT_CMD_INVERSE 4    /* inverse of NAT_CMD_REQUEST */
#define NAT_CMD_INVERSED 5   /* last inverse of NAT_CMD_REQUEST */
#define NAT_CMD_REQUEST 6    /* remotely requested traversal (or its repeat/inverse) */
#define NAT_CMD_REPLY 7      /* peer response to my traversal request, repeat or inverse */
#define NAT_CMD_REVERSE 8    /* connection reversal attempt */
#define NAT_CMD_REVERSING 9  /* connection reversal request */
#define NAT_CMD_REVERSEND 10 /* connection reversal finished */

/* peer is sending a connection reversal switch */
int nat_reverse_succeed_ (simclient client, simbool eof);

/* server has received a reversed connection */
int nat_reverse_accept_ (simsocket sock, simcontact contact, const simtype request, simclient *client);

/* connection reversal attempt (NAT_CMD_REVERSE), request (NAT_CMD_REVERSING) or finish (NAT_CMD_REVERSEND) */
int nat_reverse_exec (simclient client, int cmd);

/* attempt connection reversal unless already attempting */
int nat_reverse_attempt (simclient client);

/* send UDP start request for UDP reversal/traversal */
void nat_reverse_send_udp (simclient client);

/* peer is sending a NAT traversal switch */
int nat_traverse_succeed_ (simclient client, simbool eof);

/* internal use only */
void nat_traverse_reset (simclient client, int error);

/* attempt NAT traversal unless already connected directly */
int nat_traverse_attempt (simclient client);

/* peer is sending a NAT traversal command */
int nat_traverse_exec (simclient client, const simtype table, int cmd);

/* handle periodic traversal attempts, retries and timeouts */
void nat_periodic (simclient client, simnumber tick);

/* return NAT traversal status */
const char *nat_get_status (simclient client);

/* return NAT connection flags (CLIENT_FLAG_xxx) */
int nat_get_connected (simclient client);

/* return number of NAT traversal sockets currently open */
int nat_get_sockets (simclient client);

/* start NAT traversal thread */
int nat_init (simclient client);

/* stop NAT traversal thread */
void nat_uninit_ (simclient client);

/* debug logging */
void nat_log_traversers (const char *module, int level);

#endif
