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 }