diff --git a/platform/include/internal/proxy.h b/platform/include/internal/proxy.h index 4d3ac32..0f382e9 100644 --- a/platform/include/internal/proxy.h +++ b/platform/include/internal/proxy.h @@ -32,6 +32,7 @@ enum TFE_STAT_FIELD struct tfe_proxy_tcp_options { + /* TCP OPTIONS */ int sz_rcv_buffer; int sz_snd_buffer; int so_keepalive; @@ -39,6 +40,10 @@ struct tfe_proxy_tcp_options int tcp_keepintvl; int tcp_keepcnt; int tcp_user_timeout; + + /* TRACE FOR DEBUG */ + int tcp_ttl_upstream; + int tcp_ttl_downstream; }; struct tfe_proxy_accept_para diff --git a/platform/src/proxy.cpp b/platform/src/proxy.cpp index c95d092..14b2910 100644 --- a/platform/src/proxy.cpp +++ b/platform/src/proxy.cpp @@ -236,8 +236,10 @@ int tfe_proxy_config(struct tfe_proxy * proxy, const char * profile) { /* Worker threads */ MESA_load_profile_uint_def(profile, "main", "nr_worker_threads", &proxy->nr_work_threads, 1); + /* Debug */ MESA_load_profile_uint_def(profile, "debug", "passthrough_all_tcp", &proxy->tcp_all_passthrough, 0); + /* TCP options, -1 means unset, we shall not call setsockopt */ MESA_load_profile_int_def(profile, "tcp", "sz_rcv_buffer", &proxy->tcp_options.sz_rcv_buffer, -1); MESA_load_profile_int_def(profile, "tcp", "sz_snd_buffer", &proxy->tcp_options.sz_snd_buffer, -1); @@ -246,7 +248,9 @@ int tfe_proxy_config(struct tfe_proxy * proxy, const char * profile) MESA_load_profile_int_def(profile, "tcp", "tcp_keepintvl", &proxy->tcp_options.tcp_keepintvl, -1); MESA_load_profile_int_def(profile, "tcp", "tcp_keepcnt", &proxy->tcp_options.tcp_keepcnt, -1); MESA_load_profile_int_def(profile, "tcp", "tcp_user_timeout", &proxy->tcp_options.tcp_user_timeout, -1); - + MESA_load_profile_int_def(profile, "tcp", "tcp_ttl_upstream", &proxy->tcp_options.tcp_ttl_upstream, -1); + MESA_load_profile_int_def(profile, "tcp", "tcp_ttl_downstream", &proxy->tcp_options.tcp_ttl_downstream, -1); + return 0; } diff --git a/platform/src/tcp_stream.cpp b/platform/src/tcp_stream.cpp index 216d69b..4c3f52f 100644 --- a/platform/src/tcp_stream.cpp +++ b/platform/src/tcp_stream.cpp @@ -950,7 +950,44 @@ __errout: return NULL; } -void __stream_fd_option_setup(struct tfe_stream_private * _stream, evutil_socket_t fd) +int __fd_ttl_option_setup(struct tfe_stream_private * _stream, evutil_socket_t fd, int ttl) +{ + struct sockaddr_storage sk_storage; + socklen_t sk_storage_len = sizeof(sk_storage); + + if (getsockname(fd, (struct sockaddr *)&sk_storage, &sk_storage_len) < 0) + { + TFE_STREAM_LOG_ERROR(_stream, "getsockname(fd = %d) failed: %s", fd, strerror(errno)); + return -1; + } + + /* For IPv4, set TTL */ + unsigned int __ttl = (unsigned int)ttl; + const char * __str_family = NULL; + int ret = 0; + + if (sk_storage.ss_family == AF_INET) + { + ret = setsockopt(fd, IPPROTO_IP, IP_TTL, &__ttl, sizeof(__ttl)); + __str_family = "AF_INET"; + } + else if (sk_storage.ss_family == AF_INET6) + { + ret = setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &__ttl, sizeof(__ttl)); + __str_family = "AF_INET6"; + } + else { assert(0); } + + if(ret < 0) + { + TFE_STREAM_LOG_ERROR(_stream, "setsockopt(ttl = %u, fd = %d, family = %s) failed: %s", + __ttl, fd, __str_family, strerror(errno)); return -2; + } + + return 0; +} + +void __stream_fd_option_setup(struct tfe_stream_private * _stream, evutil_socket_t fd, tfe_conn_dir dir) { struct tfe_stream * stream = &_stream->head; struct tfe_proxy_tcp_options * tcp_options = &_stream->proxy_ref->tcp_options; @@ -1025,6 +1062,12 @@ void __stream_fd_option_setup(struct tfe_stream_private * _stream, evutil_socket } } + int __ttl = (dir == CONN_DIR_UPSTREAM) ? tcp_options->tcp_ttl_upstream : tcp_options->tcp_ttl_downstream; + if(__ttl > 0 && __fd_ttl_option_setup(_stream, fd, __ttl) < 0) + { + TFE_STREAM_LOG_ERROR(stream, "Failed at setup FD's ttl option, ttl = %d, fd = %d", __ttl, fd); + } + return; } @@ -1038,8 +1081,8 @@ int tfe_stream_init_by_fds(struct tfe_stream * stream, evutil_socket_t fd_downst _stream->log_fd_downstream = fd_downstream; _stream->log_fd_upstream = fd_upstream; - __stream_fd_option_setup(_stream, fd_downstream); - __stream_fd_option_setup(_stream, fd_upstream); + __stream_fd_option_setup(_stream, fd_downstream, CONN_DIR_DOWNSTREAM); + __stream_fd_option_setup(_stream, fd_upstream, CONN_DIR_UPSTREAM); _stream->head.addr = tfe_stream_addr_create_by_fd(fd_downstream, CONN_DIR_DOWNSTREAM); if (unlikely(_stream->head.addr == NULL))