00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "libts.h"
00031
00032 #include "P_Net.h"
00033
00034 #define SET_TCP_NO_DELAY
00035 #define SET_NO_LINGER
00036
00037
00038
00039 #define FIRST_RANDOM_PORT 16000
00040 #define LAST_RANDOM_PORT 32000
00041
00042 #define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
00043
00044 #ifndef FD_CLOEXEC
00045 #define FD_CLOEXEC 1
00046 #endif
00047
00048 int
00049 get_listen_backlog(void)
00050 {
00051 int listen_backlog = 1024;
00052
00053 REC_ReadConfigInteger(listen_backlog, "proxy.config.net.listen_backlog");
00054 return listen_backlog;
00055 }
00056
00057
00058
00059
00060
00061 char const*
00062 NetVCOptions::toString(addr_bind_style s) {
00063 return ANY_ADDR == s ? "any"
00064 : INTF_ADDR == s ? "interface"
00065 : "foreign"
00066 ;
00067 }
00068
00069 Connection::Connection()
00070 : fd(NO_FD)
00071 , is_bound(false)
00072 , is_connected(false)
00073 , sock_type(0)
00074 {
00075 memset(&addr, 0, sizeof(addr));
00076 }
00077
00078
00079 Connection::~Connection()
00080 {
00081 close();
00082 }
00083
00084
00085 int
00086 Server::accept(Connection * c)
00087 {
00088 int res = 0;
00089 socklen_t sz = sizeof(c->addr);
00090
00091 res = socketManager.accept(fd, &c->addr.sa, &sz);
00092 if (res < 0)
00093 return res;
00094 c->fd = res;
00095 if (is_debug_tag_set("iocore_net_server")) {
00096 ip_port_text_buffer ipb1, ipb2;
00097 Debug("iocore_net_server", "Connection accepted [Server]. %s -> %s\n"
00098 , ats_ip_nptop(&c->addr, ipb2, sizeof(ipb2))
00099 , ats_ip_nptop(&addr, ipb1, sizeof(ipb1))
00100 );
00101 }
00102
00103 #ifdef SET_CLOSE_ON_EXEC
00104 if ((res = safe_fcntl(fd, F_SETFD, FD_CLOEXEC)) < 0)
00105 goto Lerror;
00106 #endif
00107 if ((res = safe_nonblocking(c->fd)) < 0)
00108 goto Lerror;
00109 #ifdef SEND_BUF_SIZE
00110 socketManager.set_sndbuf_size(c->fd, SEND_BUF_SIZE);
00111 #endif
00112 #ifdef SET_SO_KEEPALIVE
00113
00114 if ((res = safe_setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, SOCKOPT_ON, sizeof(int))) < 0)
00115 goto Lerror;
00116 #endif
00117
00118 return 0;
00119
00120 Lerror:
00121 c->close();
00122 return res;
00123 }
00124
00125
00126 int
00127 Connection::close()
00128 {
00129 is_connected = false;
00130 is_bound = false;
00131
00132 if (fd >= 2) {
00133 int fd_save = fd;
00134 fd = NO_FD;
00135 return socketManager.close(fd_save);
00136 } else {
00137 fd = NO_FD;
00138 return -EBADF;
00139 }
00140 }
00141
00142 static int
00143 add_http_filter(int fd ATS_UNUSED)
00144 {
00145 int err = -1;
00146 #if defined(SOL_FILTER) && defined(FIL_ATTACH)
00147 err = setsockopt(fd, SOL_FILTER, FIL_ATTACH, "httpfilt", 9);
00148 #endif
00149 return err;
00150 }
00151
00152 int
00153 Server::setup_fd_for_listen(
00154 bool non_blocking,
00155 int recv_bufsize,
00156 int send_bufsize,
00157 bool transparent)
00158 {
00159 int res = 0;
00160
00161 ink_assert(fd != NO_FD);
00162
00163 if (http_accept_filter) {
00164 add_http_filter(fd);
00165 }
00166
00167 #ifdef SEND_BUF_SIZE
00168 {
00169 int send_buf_size = SEND_BUF_SIZE;
00170 if ((res = safe_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *) &send_buf_size, sizeof(int)) < 0)) {
00171 goto Lerror;
00172 }
00173 }
00174 #endif
00175
00176 #ifdef RECV_BUF_SIZE
00177 {
00178 int recv_buf_size = RECV_BUF_SIZE;
00179 if ((res = safe_setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *) &recv_buf_size, sizeof(int))) < 0) {
00180 goto Lerror;
00181 }
00182 }
00183 #endif
00184
00185 if (recv_bufsize) {
00186 if (socketManager.set_rcvbuf_size(fd, recv_bufsize)) {
00187
00188 int rbufsz = ROUNDUP(recv_bufsize, 1024);
00189 while (rbufsz) {
00190 if (socketManager.set_rcvbuf_size(fd, rbufsz)) {
00191 rbufsz -= 1024;
00192 } else {
00193 break;
00194 }
00195 }
00196 }
00197 }
00198
00199 if (send_bufsize) {
00200 if (socketManager.set_sndbuf_size(fd, send_bufsize)) {
00201
00202 int sbufsz = ROUNDUP(send_bufsize, 1024);
00203 while (sbufsz) {
00204 if (socketManager.set_sndbuf_size(fd, sbufsz)) {
00205 sbufsz -= 1024;
00206 } else {
00207 break;
00208 }
00209 }
00210 }
00211 }
00212
00213 #ifdef SET_CLOSE_ON_EXEC
00214 if ((res = safe_fcntl(fd, F_SETFD, FD_CLOEXEC)) < 0) {
00215 goto Lerror;
00216 }
00217 #endif
00218
00219 #ifdef SET_NO_LINGER
00220 {
00221 struct linger l;
00222 l.l_onoff = 0;
00223 l.l_linger = 0;
00224 if ((res = safe_setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *) &l, sizeof(l))) < 0) {
00225 goto Lerror;
00226 }
00227 }
00228 #endif
00229
00230 if (ats_is_ip6(&addr) && (res = safe_setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, SOCKOPT_ON, sizeof(int))) < 0) {
00231 goto Lerror;
00232 }
00233
00234 if ((res = safe_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, SOCKOPT_ON, sizeof(int))) < 0) {
00235 goto Lerror;
00236 }
00237
00238 #ifdef SET_TCP_NO_DELAY
00239 if ((res = safe_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, SOCKOPT_ON, sizeof(int))) < 0) {
00240 goto Lerror;
00241 }
00242 #endif
00243
00244 #ifdef SET_SO_KEEPALIVE
00245
00246 if ((res = safe_setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, SOCKOPT_ON, sizeof(int))) < 0) {
00247 goto Lerror;
00248 }
00249 #endif
00250
00251 if (transparent) {
00252 #if TS_USE_TPROXY
00253 Debug("http_tproxy", "Listen port inbound transparency enabled.\n");
00254 if (safe_setsockopt(fd, SOL_IP, TS_IP_TRANSPARENT, SOCKOPT_ON, sizeof(int)) < 0) {
00255 Error("[Server::listen] Unable to set transparent socket option [%d] %s\n", errno, strerror(errno));
00256 _exit(1);
00257 }
00258 #else
00259 Error("[Server::listen] Transparency requested but TPROXY not configured\n");
00260 #endif
00261 }
00262
00263 #if defined(TCP_MAXSEG)
00264 if (NetProcessor::accept_mss > 0) {
00265 if ((res = safe_setsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, (char *) &NetProcessor::accept_mss, sizeof(int))) < 0) {
00266 goto Lerror;
00267 }
00268 }
00269 #endif
00270
00271 if (non_blocking) {
00272 if ((res = safe_nonblocking(fd)) < 0) {
00273 goto Lerror;
00274 }
00275 }
00276
00277 return 0;
00278
00279 Lerror:
00280 res = -errno;
00281
00282
00283 if (fd != NO_FD) {
00284 close();
00285 fd = NO_FD;
00286 }
00287
00288 return res;
00289 }
00290
00291
00292 int
00293 Server::listen(bool non_blocking, int recv_bufsize, int send_bufsize, bool transparent)
00294 {
00295 ink_assert(fd == NO_FD);
00296 int res = 0;
00297 int namelen;
00298
00299 if (!ats_is_ip(&accept_addr)) {
00300 ats_ip4_set(&addr, INADDR_ANY, 0);
00301 } else {
00302 ats_ip_copy(&addr, &accept_addr);
00303 }
00304
00305 fd = res = socketManager.socket(addr.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
00306 if (res < 0) {
00307 goto Lerror;
00308 }
00309
00310 res = setup_fd_for_listen(non_blocking, recv_bufsize, send_bufsize, transparent);
00311 if (res < 0) {
00312 goto Lerror;
00313 }
00314
00315 if ((res = socketManager.ink_bind(fd, &addr.sa, ats_ip_size(&addr.sa), IPPROTO_TCP)) < 0) {
00316 goto Lerror;
00317 }
00318
00319 if ((res = safe_listen(fd, get_listen_backlog())) < 0) {
00320 goto Lerror;
00321 }
00322
00323
00324 namelen = sizeof(addr);
00325 if ((res = safe_getsockname(fd, &addr.sa, &namelen))) {
00326 goto Lerror;
00327 }
00328
00329 return 0;
00330
00331 Lerror:
00332 if (fd != NO_FD) {
00333 close();
00334 fd = NO_FD;
00335 }
00336
00337 Error("Could not bind or listen to port %d (error: %d)", ats_ip_port_host_order(&addr), res);
00338 return res;
00339 }