~ubuntu-branches/ubuntu/wily/trafficserver/wily

« back to all changes in this revision

Viewing changes to iocore/net/Connection.cc

  • Committer: Package Import Robot
  • Author(s): Adam Conrad
  • Date: 2012-12-17 22:28:16 UTC
  • mfrom: (5.1.8 raring-proposed)
  • Revision ID: package-import@ubuntu.com-20121217222816-7xwjsx5k76zkb63d
Tags: 3.2.0-1ubuntu1
* Revert FreeBSD strerror_r() fixes that give errors with glibc 2.16.
* Apply patch from Konstantinos Margaritis to define barriers on ARM.

Show diffs side-by-side

added added

removed removed

Lines of Context:
68
68
  : fd(NO_FD)
69
69
  , is_bound(false)
70
70
  , is_connected(false)
 
71
  , sock_type(0)
71
72
{
72
 
  memset(&sa, 0, sizeof(struct sockaddr_storage));
 
73
  memset(&addr, 0, sizeof(addr));
73
74
}
74
75
 
75
76
 
83
84
Server::accept(Connection * c)
84
85
{
85
86
  int res = 0;
86
 
  socklen_t sz = sizeof(c->sa);
 
87
  socklen_t sz = sizeof(c->addr);
87
88
 
88
 
  res = socketManager.accept(fd, (struct sockaddr *)&c->sa, &sz);
 
89
  res = socketManager.accept(fd, &c->addr.sa, &sz);
89
90
  if (res < 0)
90
91
    return res;
91
92
  c->fd = res;
 
93
  if (is_debug_tag_set("iocore_net_server")) {
 
94
    ip_port_text_buffer ipb1, ipb2;
 
95
      Debug("iocore_net_server", "Connection accepted [Server]. %s -> %s\n"
 
96
        , ats_ip_nptop(&c->addr, ipb2, sizeof(ipb2))
 
97
        , ats_ip_nptop(&addr, ipb1, sizeof(ipb1))
 
98
      );
 
99
  }
92
100
 
93
101
#ifdef SET_CLOSE_ON_EXEC
94
102
  if ((res = safe_fcntl(fd, F_SETFD, 1)) < 0)
101
109
#endif
102
110
#ifdef SET_SO_KEEPALIVE
103
111
  // enables 2 hour inactivity probes, also may fix IRIX FIN_WAIT_2 leak
104
 
  if ((res = safe_setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, ON, sizeof(int))) < 0)
 
112
  if ((res = safe_setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, SOCKOPT_ON, sizeof(int))) < 0)
105
113
    goto Lerror;
106
114
#endif
107
115
 
128
136
  }
129
137
}
130
138
 
 
139
static int
 
140
add_http_filter(int fd) {
 
141
  int err = -1;
 
142
#if defined(SOL_FILTER) && defined(FIL_ATTACH)
 
143
  err = setsockopt(fd, SOL_FILTER, FIL_ATTACH, "httpfilt", 9);
 
144
#endif
 
145
  return err;
 
146
}
 
147
 
131
148
int
132
 
Server::setup_fd_for_listen(bool non_blocking, int recv_bufsize, int send_bufsize)
133
 
{
 
149
Server::setup_fd_for_listen(
 
150
  bool non_blocking,
 
151
  int recv_bufsize,
 
152
  int send_bufsize,
 
153
  bool transparent
 
154
) {
 
155
 
134
156
  int res = 0;
 
157
 
 
158
  if (http_accept_filter)
 
159
    add_http_filter(fd);
 
160
 
135
161
#ifdef SEND_BUF_SIZE
136
162
  {
137
163
    int send_buf_size = SEND_BUF_SIZE;
184
210
  }
185
211
#endif
186
212
#ifdef SET_TCP_NO_DELAY
187
 
  if ((res = safe_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, ON, sizeof(int))) < 0)
 
213
  if ((res = safe_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, SOCKOPT_ON, sizeof(int))) < 0)
188
214
    goto Lerror;
189
215
#endif
190
216
#ifdef SET_SO_KEEPALIVE
191
217
  // enables 2 hour inactivity probes, also may fix IRIX FIN_WAIT_2 leak
192
 
  if ((res = safe_setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, ON, sizeof(int))) < 0)
 
218
  if ((res = safe_setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, SOCKOPT_ON, sizeof(int))) < 0)
193
219
    goto Lerror;
194
220
#endif
195
221
 
208
234
    if ((res = safe_nonblocking(fd)) < 0)
209
235
      goto Lerror;
210
236
  {
211
 
    int namelen = sizeof(sa);
212
 
    if ((res = safe_getsockname(fd, (struct sockaddr *) &sa, &namelen)))
 
237
    int namelen = sizeof(addr);
 
238
    if ((res = safe_getsockname(fd, &addr.sa, &namelen)))
213
239
      goto Lerror;
214
240
  }
 
241
 
 
242
  if (transparent) {
 
243
#if TS_USE_TPROXY
 
244
    int transparent_value = 1;
 
245
    Debug("http_tproxy", "Listen port inbound transparency enabled.\n");
 
246
    if (setsockopt(fd, SOL_IP, TS_IP_TRANSPARENT, &transparent_value, sizeof(transparent_value)) == -1) {
 
247
      Error("[Server::setup_fd_for_listen] Unable to set transparent socket option [%d] %s\n", errno, strerror(errno));
 
248
      _exit(1);
 
249
    }
 
250
#else
 
251
    Error("[Server::setup_fd_for_listen] Transparency requested but TPROXY not configured\n");
 
252
#endif
 
253
  }
 
254
 
215
255
  return 0;
216
256
Lerror:
217
257
  res = -errno;
223
263
 
224
264
 
225
265
int
226
 
Server::listen(int port_number, int domain, bool non_blocking, int recv_bufsize, int send_bufsize)
 
266
Server::listen(bool non_blocking, int recv_bufsize, int send_bufsize, bool transparent)
227
267
{
228
268
  ink_assert(fd == NO_FD);
229
269
  int res = 0;
230
 
  int gai_errno = 0;
231
 
 
232
 
  char port[6] = {'\0'};
233
 
  struct addrinfo hints;
234
 
  struct addrinfo *ai_res = NULL;
235
 
  struct addrinfo *ai = NULL;
236
 
  socklen_t addrlen = 0;  // keep track of length of socket address info
237
 
  snprintf(port, sizeof(port), "%d", port_number);
238
 
 
239
 
  memset(&hints, 0, sizeof(hints));
240
 
  hints.ai_family = domain;
241
 
  hints.ai_socktype = SOCK_STREAM;
242
 
  hints.ai_flags = AI_PASSIVE|AI_NUMERICHOST|AI_ADDRCONFIG;
243
 
  gai_errno = getaddrinfo(accept_ip_str, port, &hints, &ai_res);
244
 
  if(0 != gai_errno) {
245
 
    Error("getaddrinfo error %i: %s", gai_errno, gai_strerror(gai_errno));
246
 
    return -1;
 
270
  int namelen;
 
271
 
 
272
  if (!ats_is_ip(&accept_addr)) {
 
273
    ats_ip4_set(&addr, INADDR_ANY,0);
 
274
  } else {
 
275
    ats_ip_copy(&addr, &accept_addr);
247
276
  }
248
277
 
249
 
  ai = ai_res;
250
 
 
251
 
  res = socketManager.socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
252
 
 
253
 
  memset(&sa, 0, sizeof(sa));
254
 
  addrlen = ai->ai_addrlen;  // save value for later since ai will be freed asap
255
 
  memcpy(&sa, ai->ai_addr, ai->ai_addrlen);
256
 
 
257
 
  freeaddrinfo(ai_res);
 
278
  res = socketManager.socket(addr.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
258
279
 
259
280
  if (res < 0)
260
281
    return res;
261
282
  fd = res;
262
283
 
 
284
  if (http_accept_filter)
 
285
    add_http_filter(fd);
 
286
 
263
287
#ifdef SEND_BUF_SIZE
264
288
  {
265
289
    int send_buf_size = SEND_BUF_SIZE;
316
340
  }
317
341
#endif
318
342
 
319
 
  if (domain == AF_INET6 && (res = safe_setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, ON, sizeof(int))) < 0)
320
 
    goto Lerror;
321
 
 
322
 
  if ((res = safe_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, ON, sizeof(int))) < 0)
323
 
    goto Lerror;
324
 
 
325
 
  if ((res = socketManager.ink_bind(fd, (struct sockaddr *) &sa, addrlen, IPPROTO_TCP)) < 0) {
 
343
  if (ats_is_ip6(&addr) && (res = safe_setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, SOCKOPT_ON, sizeof(int))) < 0)
 
344
    goto Lerror;
 
345
 
 
346
  if ((res = safe_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, SOCKOPT_ON, sizeof(int))) < 0)
 
347
    goto Lerror;
 
348
 
 
349
  if ((res = socketManager.ink_bind(fd, &addr.sa, ats_ip_size(&addr.sa), IPPROTO_TCP)) < 0) {
326
350
    goto Lerror;
327
351
  }
328
352
#ifdef SET_TCP_NO_DELAY
329
 
  if ((res = safe_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, ON, sizeof(int))) < 0)
 
353
  if ((res = safe_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, SOCKOPT_ON, sizeof(int))) < 0)
330
354
    goto Lerror;
331
355
#endif
332
356
#ifdef SET_SO_KEEPALIVE
333
357
  // enables 2 hour inactivity probes, also may fix IRIX FIN_WAIT_2 leak
334
 
  if ((res = safe_setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, ON, sizeof(int))) < 0)
 
358
  if ((res = safe_setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, SOCKOPT_ON, sizeof(int))) < 0)
335
359
    goto Lerror;
336
360
#endif
337
361
 
 
362
  if (transparent) {
 
363
#if TS_USE_TPROXY
 
364
    int transparent_value = 1;
 
365
    Debug("http_tproxy", "Listen port inbound transparency enabled.\n");
 
366
    if (setsockopt(fd, SOL_IP, TS_IP_TRANSPARENT, &transparent_value, sizeof(transparent_value)) == -1) {
 
367
      Error("[Server::listen] Unable to set transparent socket option [%d] %s\n", errno, strerror(errno));
 
368
      _exit(1);
 
369
    }
 
370
#else
 
371
    Error("[Server::listen] Transparency requested but TPROXY not configured\n");
 
372
#endif
 
373
  }
 
374
 
338
375
#if defined(linux)
339
376
  if (NetProcessor::accept_mss > 0)
340
377
    if ((res = safe_setsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, (char *) &NetProcessor::accept_mss, sizeof(int))) < 0)
346
383
  if (non_blocking)
347
384
    if ((res = safe_nonblocking(fd)) < 0)
348
385
      goto Lerror;
349
 
  if (!port_number) {
350
 
    int namelen = sizeof(sa);
351
 
    if ((res = safe_getsockname(fd, (struct sockaddr *) &sa, &namelen)))
 
386
  // Original just did this on port == 0.
 
387
  namelen = sizeof(addr);
 
388
  if ((res = safe_getsockname(fd, &addr.sa, &namelen)))
352
389
      goto Lerror;
353
 
  }
354
390
  return 0;
355
391
 
356
392
Lerror:
357
393
  if (fd != NO_FD)
358
394
    close();
359
 
  Error("Could not bind or listen to port %d (error: %d)", port_number, res);
 
395
  Error("Could not bind or listen to port %d (error: %d)", ats_ip_port_host_order(&addr), res);
360
396
  return res;
361
397
}