blob: 9c2540bcbfe5f2a112f93731d7bc210bdbcb7d08 [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
3 * Copyright 2014, Google Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34#include "src/core/endpoint/socket_utils.h"
35
36#include <limits.h>
37#include <fcntl.h>
38#include <netinet/in.h>
39#include <netinet/tcp.h>
40#include <stdio.h>
41#include <sys/types.h>
42#include <sys/socket.h>
43#include <unistd.h>
44#include <string.h>
45#include <errno.h>
46
47/* set a socket to non blocking mode */
48int grpc_set_socket_nonblocking(int fd, int non_blocking) {
49 int oldflags = fcntl(fd, F_GETFL, 0);
50 if (oldflags < 0) {
51 return 0;
52 }
53
54 if (non_blocking) {
55 oldflags |= O_NONBLOCK;
56 } else {
57 oldflags &= ~O_NONBLOCK;
58 }
59
60 if (fcntl(fd, F_SETFL, oldflags) != 0) {
61 return 0;
62 }
63
64 return 1;
65}
66
67/* set a socket to close on exec */
68int grpc_set_socket_cloexec(int fd, int close_on_exec) {
69 int oldflags = fcntl(fd, F_GETFD, 0);
70 if (oldflags < 0) {
71 return 0;
72 }
73
74 if (close_on_exec) {
75 oldflags |= FD_CLOEXEC;
76 } else {
77 oldflags &= ~FD_CLOEXEC;
78 }
79
80 if (fcntl(fd, F_SETFD, oldflags) != 0) {
81 return 0;
82 }
83
84 return 1;
85}
86
87/* set a socket to reuse old addresses */
88int grpc_set_socket_reuse_addr(int fd, int reuse) {
89 int val = (reuse != 0);
90 int newval;
91 socklen_t intlen = sizeof(newval);
92 return 0 == setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) &&
93 0 == getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &newval, &intlen) &&
94 newval == val;
95}
96
97/* disable nagle */
98int grpc_set_socket_low_latency(int fd, int low_latency) {
99 int val = (low_latency != 0);
100 int newval;
101 socklen_t intlen = sizeof(newval);
102 return 0 == setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)) &&
103 0 == getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &newval, &intlen) &&
104 newval == val;
105}