@@ -169,6 +169,18 @@ static inline void set_reuse_port(int sockfd) {
169
169
}
170
170
}
171
171
172
+ static inline void set_tfo_accept (int sockfd ) {
173
+ if (setsockopt (sockfd , IPPROTO_TCP , TCP_FASTOPEN , & (int ){5 }, sizeof (int )) < 0 ) {
174
+ LOGERR ("[set_tfo_accept] setsockopt(%d, TCP_FASTOPEN): %s" , sockfd , my_strerror (errno ));
175
+ }
176
+ }
177
+
178
+ static inline void set_tcp_syncnt (int sockfd , int syncnt ) {
179
+ if (setsockopt (sockfd , IPPROTO_TCP , TCP_SYNCNT , & syncnt , sizeof (int )) < 0 ) {
180
+ LOGERR ("[set_tcp_syncnt] setsockopt(%d, TCP_SYNCNT): %s" , sockfd , my_strerror (errno ));
181
+ }
182
+ }
183
+
172
184
static inline void set_tcp_nodelay (int sockfd ) {
173
185
if (setsockopt (sockfd , IPPROTO_TCP , TCP_NODELAY , & (int ){1 }, sizeof (int )) < 0 ) {
174
186
LOGERR ("[set_tcp_nodelay] setsockopt(%d, TCP_NODELAY): %s" , sockfd , my_strerror (errno ));
@@ -181,15 +193,32 @@ static inline void set_tcp_quickack(int sockfd) {
181
193
}
182
194
}
183
195
184
- static inline void set_tfo_accept (int sockfd ) {
185
- if (setsockopt (sockfd , IPPROTO_TCP , TCP_FASTOPEN , & (int ){ 5 }, sizeof (int )) < 0 ) {
186
- LOGERR ("[set_tfo_accept ] setsockopt(%d, TCP_FASTOPEN ): %s" , sockfd , my_strerror (errno ));
196
+ static inline void set_tcp_solinger0 (int sockfd ) {
197
+ if (setsockopt (sockfd , SOL_SOCKET , SO_LINGER , & (struct linger ){. l_onoff = 1 , . l_linger = 0 }, sizeof (struct linger )) < 0 ) {
198
+ LOGERR ("[set_tcp_solinger0 ] setsockopt(%d, SO_LINGER ): %s" , sockfd , my_strerror (errno ));
187
199
}
188
200
}
189
201
190
- static inline void set_tcp_syncnt (int sockfd , int syncnt ) {
191
- if (setsockopt (sockfd , IPPROTO_TCP , TCP_SYNCNT , & syncnt , sizeof (int )) < 0 ) {
192
- LOGERR ("[set_tcp_syncnt] setsockopt(%d, TCP_SYNCNT): %s" , sockfd , my_strerror (errno ));
202
+ static inline void set_tcp_keepalive (int sockfd ) {
203
+ /* enable tcp_keepalive */
204
+ if (setsockopt (sockfd , SOL_SOCKET , SO_KEEPALIVE , & (int ){1 }, sizeof (int )) < 0 ) {
205
+ LOGERR ("[set_tcp_keepalive] setsockopt(%d, SO_KEEPALIVE): %s" , sockfd , my_strerror (errno ));
206
+ return ;
207
+ }
208
+ /* tcp connection idle sec */
209
+ if (setsockopt (sockfd , IPPROTO_TCP , TCP_KEEPIDLE , & (int ){60 }, sizeof (int )) < 0 ) {
210
+ LOGERR ("[set_tcp_keepalive] setsockopt(%d, TCP_KEEPIDLE): %s" , sockfd , my_strerror (errno ));
211
+ return ;
212
+ }
213
+ /* keepalive probe retry max count */
214
+ if (setsockopt (sockfd , IPPROTO_TCP , TCP_KEEPCNT , & (int ){3 }, sizeof (int )) < 0 ) {
215
+ LOGERR ("[set_tcp_keepalive] setsockopt(%d, TCP_KEEPCNT): %s" , sockfd , my_strerror (errno ));
216
+ return ;
217
+ }
218
+ /* keepalive probe retry interval sec */
219
+ if (setsockopt (sockfd , IPPROTO_TCP , TCP_KEEPINTVL , & (int ){5 }, sizeof (int )) < 0 ) {
220
+ LOGERR ("[set_tcp_keepalive] setsockopt(%d, TCP_KEEPINTVL): %s" , sockfd , my_strerror (errno ));
221
+ return ;
193
222
}
194
223
}
195
224
@@ -225,12 +254,7 @@ static inline void setup_accepted_sockfd(int sockfd) {
225
254
set_non_block (sockfd );
226
255
set_tcp_nodelay (sockfd );
227
256
set_tcp_quickack (sockfd );
228
- }
229
-
230
- static inline void send_reset_to_peer (int sockfd ) {
231
- if (setsockopt (sockfd , SOL_SOCKET , SO_LINGER , & (struct linger ){.l_onoff = 1 , .l_linger = 0 }, sizeof (struct linger )) < 0 ) {
232
- LOGERR ("[send_reset_to_peer] setsockopt(%d, SO_LINGER): %s" , sockfd , my_strerror (errno ));
233
- }
257
+ set_tcp_keepalive (sockfd );
234
258
}
235
259
236
260
static inline int new_nonblock_sockfd (int family , int sktype ) {
@@ -257,6 +281,7 @@ int new_tcp_connect_sockfd(int family, uint8_t tcp_syncnt) {
257
281
int sockfd = new_nonblock_sockfd (family , SOCK_STREAM );
258
282
set_tcp_nodelay (sockfd );
259
283
set_tcp_quickack (sockfd );
284
+ set_tcp_keepalive (sockfd );
260
285
if (tcp_syncnt ) set_tcp_syncnt (sockfd , tcp_syncnt );
261
286
return sockfd ;
262
287
}
@@ -320,50 +345,31 @@ bool get_udp_orig_dstaddr(int family, struct msghdr *msg, void *dstaddr) {
320
345
return false;
321
346
}
322
347
323
- bool tcp_accept ( int sockfd , int * conn_sockfd , void * from_skaddr ) {
324
- * conn_sockfd = accept ( sockfd , from_skaddr , from_skaddr ? & ( socklen_t ){ sizeof ( skaddr6_t )} : NULL );
325
- if ( * conn_sockfd < 0 && errno != EAGAIN && errno != EWOULDBLOCK ) return false ;
326
- if (* conn_sockfd >= 0 ) setup_accepted_sockfd (* conn_sockfd );
327
- return true ;
348
+ /* same as `accept()`, just a simple wrapper */
349
+ int tcp_accept ( int sockfd , void * addr , socklen_t * addrlen ) {
350
+ int newsockfd = accept ( sockfd , addr , addrlen ) ;
351
+ if (newsockfd >= 0 ) setup_accepted_sockfd (newsockfd );
352
+ return newsockfd ;
328
353
}
329
354
330
- bool tcp_connect (int sockfd , const void * skaddr , const void * data , size_t datalen , ssize_t * nsend ) {
331
- socklen_t skaddrlen = ((skaddr4_t * )skaddr )-> sin_family == AF_INET ? sizeof (skaddr4_t ) : sizeof (skaddr6_t );
332
- if (data && datalen && nsend ) {
333
- if ((* nsend = sendto (sockfd , data , datalen , MSG_FASTOPEN , skaddr , skaddrlen )) < 0 && errno != EINPROGRESS ) return false;
355
+ /* return: is_succ, tfo_succ if tfo_nsend >= 0 */
356
+ bool tcp_connect (int sockfd , const void * addr , const void * tfo_data , size_t tfo_datalen , ssize_t * tfo_nsend ) {
357
+ socklen_t addrlen = ((skaddr4_t * )addr )-> sin_family == AF_INET ? sizeof (skaddr4_t ) : sizeof (skaddr6_t );
358
+ if (tfo_data && tfo_datalen && tfo_nsend ) {
359
+ if ((* tfo_nsend = sendto (sockfd , tfo_data , tfo_datalen , MSG_FASTOPEN , addr , addrlen )) < 0 && errno != EINPROGRESS ) return false;
334
360
} else {
335
- if (connect (sockfd , skaddr , skaddrlen ) < 0 && errno != EINPROGRESS ) return false;
361
+ if (connect (sockfd , addr , addrlen ) < 0 && errno != EINPROGRESS ) return false;
336
362
}
337
363
return true;
338
364
}
339
365
366
+ /* on connect error, errno is set appropriately */
340
367
bool tcp_has_error (int sockfd ) {
341
368
return getsockopt (sockfd , SOL_SOCKET , SO_ERROR , & errno , & (socklen_t ){sizeof (errno )}) < 0 || errno ;
342
369
}
343
370
344
- bool tcp_recv_data (int sockfd , void * data , size_t datalen , size_t * nrecv , bool * is_eof ) {
345
- ssize_t ret = recv (sockfd , data + * nrecv , datalen - * nrecv , 0 );
346
- if (ret < 0 && errno != EAGAIN && errno != EWOULDBLOCK ) {
347
- return false;
348
- } else if (ret == 0 ) {
349
- * is_eof = true;
350
- } else if (ret > 0 ) {
351
- * nrecv += ret ;
352
- }
353
- return true;
354
- }
355
-
356
- bool tcp_send_data (int sockfd , const void * data , size_t datalen , size_t * nsend ) {
357
- ssize_t ret = send (sockfd , data + * nsend , datalen - * nsend , 0 );
358
- if (ret < 0 && errno != EAGAIN && errno != EWOULDBLOCK ) {
359
- return false;
360
- } else if (ret > 0 ) {
361
- * nsend += ret ;
362
- }
363
- return true;
364
- }
365
-
371
+ /* set so_linger(delay=0) and call close(sockfd) */
366
372
void tcp_close_by_rst (int sockfd ) {
367
- send_reset_to_peer (sockfd );
373
+ set_tcp_solinger0 (sockfd );
368
374
close (sockfd );
369
375
}
0 commit comments