2929/** Seconds since last direct UDP packet was received before the connection is considered dead */
3030#define GCC_UDP_DIRECT_TIMEOUT (GC_PING_TIMEOUT + 4)
3131
32+ /** Seconds since last direct UDP packet was sent before we can try again. Cheap NAT hole punch */
33+ #define GCC_UDP_DIRECT_RETRY 1
34+
3235/** Returns true if array entry does not contain an active packet. */
3336non_null ()
3437static bool array_entry_is_empty (const GC_Message_Array_Entry * array_entry )
@@ -595,7 +598,7 @@ void gcc_resend_packets(const GC_Chat *chat, GC_Connection *gconn)
595598 }
596599}
597600
598- bool gcc_send_packet (const GC_Chat * chat , const GC_Connection * gconn , const uint8_t * packet , uint16_t length )
601+ bool gcc_send_packet (const GC_Chat * chat , GC_Connection * gconn , const uint8_t * packet , uint16_t length )
599602{
600603 if (packet == nullptr || length == 0 ) {
601604 return false;
@@ -608,16 +611,20 @@ bool gcc_send_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint
608611 return (uint16_t ) sendpacket (chat -> net , & gconn -> addr .ip_port , packet , length ) == length ;
609612 }
610613
611- if ((uint16_t ) sendpacket (chat -> net , & gconn -> addr .ip_port , packet , length ) == length ) {
612- direct_send_attempt = true;
614+ if (gcc_conn_should_try_direct (chat -> mono_time , gconn )) {
615+ gconn -> last_sent_direct_try_time = mono_time_get (chat -> mono_time );
616+
617+ if ((uint16_t ) sendpacket (chat -> net , & gconn -> addr .ip_port , packet , length ) == length ) {
618+ direct_send_attempt = true;
619+ }
613620 }
614621 }
615622
616623 const int ret = send_packet_tcp_connection (chat -> tcp_conn , gconn -> tcp_connection_num , packet , length );
617624 return ret == 0 || direct_send_attempt ;
618625}
619626
620- int gcc_encrypt_and_send_lossless_packet (const GC_Chat * chat , const GC_Connection * gconn , const uint8_t * data ,
627+ int gcc_encrypt_and_send_lossless_packet (const GC_Chat * chat , GC_Connection * gconn , const uint8_t * data ,
621628 uint16_t length , uint64_t message_id , uint8_t packet_type )
622629{
623630 const uint16_t packet_size = gc_get_wrapped_packet_size (length , NET_PACKET_GC_LOSSLESS );
@@ -659,6 +666,11 @@ bool gcc_conn_is_direct(const Mono_Time *mono_time, const GC_Connection *gconn)
659666 return GCC_UDP_DIRECT_TIMEOUT + gconn -> last_received_direct_time > mono_time_get (mono_time );
660667}
661668
669+ bool gcc_conn_should_try_direct (const Mono_Time * mono_time , const GC_Connection * gconn )
670+ {
671+ return mono_time_is_timeout (mono_time , gconn -> last_sent_direct_try_time , GCC_UDP_DIRECT_RETRY );
672+ }
673+
662674bool gcc_direct_conn_is_possible (const GC_Chat * chat , const GC_Connection * gconn )
663675{
664676 return !net_family_is_unspec (gconn -> addr .ip_port .ip .family ) && !net_family_is_unspec (net_family (chat -> net ));
0 commit comments