| 108 | NetVCOptions const Connection::DEFAULT_OPTIONS; |
| 109 | |
| 110 | int |
| 111 | Connection::open(NetVCOptions const &opt) |
| 112 | { |
| 113 | ink_assert(!sock.is_ok()); |
| 114 | |
| 115 | IpEndpoint local_addr; |
| 116 | sock_type = NetVCOptions::USE_UDP == opt.ip_proto ? SOCK_DGRAM : SOCK_STREAM; |
| 117 | int family; |
| 118 | |
| 119 | // Need to do address calculations first, so we can determine the |
| 120 | // address family for socket creation. |
| 121 | ink_zero(local_addr); |
| 122 | |
| 123 | bool is_any_address = false; |
| 124 | if (NetVCOptions::FOREIGN_ADDR == opt.addr_binding || NetVCOptions::INTF_ADDR == opt.addr_binding) { |
| 125 | // Same for now, transparency for foreign addresses must be handled |
| 126 | // *after* the socket is created, and we need to do this calculation |
| 127 | // before the socket to get the IP family correct. |
| 128 | ink_release_assert(opt.local_ip.isValid()); |
| 129 | local_addr.assign(opt.local_ip, htons(opt.local_port)); |
| 130 | family = opt.local_ip.family(); |
| 131 | } else { |
| 132 | // No local address specified, so use family option if possible. |
| 133 | family = ats_is_ip(opt.ip_family) ? opt.ip_family : AF_INET; |
| 134 | local_addr.setToAnyAddr(family); |
| 135 | is_any_address = true; |
| 136 | local_addr.network_order_port() = htons(opt.local_port); |
| 137 | } |
| 138 | |
| 139 | sock = UnixSocket{family, sock_type, 0}; |
| 140 | if (!sock.is_ok()) { |
| 141 | return -errno; |
| 142 | } |
| 143 | |
| 144 | // mark fd for close until we succeed. |
| 145 | cleaner<Connection> cleanup(this, &Connection::_cleanup); |
| 146 | |
| 147 | // Try setting the various socket options, if requested. |
| 148 | |
| 149 | if (-1 == sock.enable_option(SOL_SOCKET, SO_REUSEADDR)) { |
| 150 | return -errno; |
| 151 | } |
| 152 | |
| 153 | if (NetVCOptions::FOREIGN_ADDR == opt.addr_binding) { |
| 154 | static char const *const DEBUG_TEXT = "::open setsockopt() IP_TRANSPARENT"; |
| 155 | #if TS_USE_TPROXY |
| 156 | if (-1 == sock.enable_option(SOL_IP, TS_IP_TRANSPARENT)) { |
| 157 | Dbg(dbg_ctl_socket, "%s - fail %d:%s", DEBUG_TEXT, errno, strerror(errno)); |
| 158 | return -errno; |
| 159 | } else { |
| 160 | Dbg(dbg_ctl_socket, "%s set", DEBUG_TEXT); |
| 161 | } |
| 162 | #else |
| 163 | Dbg(dbg_ctl_socket, "%s - requested but TPROXY not configured", DEBUG_TEXT); |
| 164 | #endif |
| 165 | } |
| 166 | |
| 167 | if (!opt.f_blocking_connect && -1 == sock.set_nonblocking()) { |
no test coverage detected