Changeset 988 for vendor/current/source4/lib/socket
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- Location:
- vendor/current/source4/lib/socket
- Files:
-
- 1 deleted
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source4/lib/socket/access.c
r740 r988 28 28 29 29 The code has been considerably changed from the original. Bug reports 30 should be sent to samba @samba.org30 should be sent to samba-technical@lists.samba.org 31 31 */ 32 32 … … 250 250 251 251 /* return true if access should be allowed */ 252 bool allow_access(TALLOC_CTX *mem_ctx,253 254 252 bool socket_allow_access(TALLOC_CTX *mem_ctx, 253 const char **deny_list, const char **allow_list, 254 const char *cname, const char *caddr) 255 255 { 256 256 bool ret; … … 347 347 } 348 348 349 ret = allow_access(mem_ctx, deny_list, allow_list, name, addr->addr);349 ret = socket_allow_access(mem_ctx, deny_list, allow_list, name, addr->addr); 350 350 351 351 if (ret) { -
vendor/current/source4/lib/socket/connect.c
r414 r988 59 59 } 60 60 61 fde = event_add_fd(result->event_ctx, result,61 fde = tevent_add_fd(result->event_ctx, result, 62 62 socket_get_fd(state->sock), 63 EVENT_FD_READ|EVENT_FD_WRITE,63 TEVENT_FD_READ|TEVENT_FD_WRITE, 64 64 socket_connect_handler, result); 65 65 composite_nomem(fde, result); -
vendor/current/source4/lib/socket/connect_multi.c
r740 r988 34 34 */ 35 35 struct connect_multi_state { 36 struct socket_address *server_address; 36 struct socket_address **server_address; 37 unsigned num_address, current_address, current_port; 37 38 int num_ports; 38 39 uint16_t *ports; … … 42 43 43 44 int num_connects_sent, num_connects_recv; 45 46 struct socket_connect_multi_ex *ex; 44 47 }; 45 48 … … 59 62 static void connect_multi_next_socket(struct composite_context *result); 60 63 static void continue_one(struct composite_context *creq); 64 static void continue_one_ex(struct tevent_req *subreq); 65 66 /* 67 setup an async socket_connect, with multiple ports 68 */ 69 _PUBLIC_ struct composite_context *socket_connect_multi_ex_send( 70 TALLOC_CTX *mem_ctx, 71 const char *server_name, 72 int num_server_ports, 73 uint16_t *server_ports, 74 struct resolve_context *resolve_ctx, 75 struct tevent_context *event_ctx, 76 struct socket_connect_multi_ex *ex) 77 { 78 struct composite_context *result; 79 struct connect_multi_state *multi; 80 int i; 81 82 struct nbt_name name; 83 struct composite_context *creq; 84 85 result = talloc_zero(mem_ctx, struct composite_context); 86 if (result == NULL) return NULL; 87 result->state = COMPOSITE_STATE_IN_PROGRESS; 88 result->event_ctx = event_ctx; 89 90 multi = talloc_zero(result, struct connect_multi_state); 91 if (composite_nomem(multi, result)) goto failed; 92 result->private_data = multi; 93 94 multi->num_ports = num_server_ports; 95 multi->ports = talloc_array(multi, uint16_t, multi->num_ports); 96 if (composite_nomem(multi->ports, result)) goto failed; 97 98 for (i=0; i<multi->num_ports; i++) { 99 multi->ports[i] = server_ports[i]; 100 } 101 102 multi->ex = ex; 103 104 /* 105 we don't want to do the name resolution separately 106 for each port, so start it now, then only start on 107 the real sockets once we have an IP 108 */ 109 make_nbt_name_server(&name, server_name); 110 111 creq = resolve_name_all_send(resolve_ctx, multi, 0, multi->ports[0], &name, result->event_ctx); 112 if (composite_nomem(creq, result)) goto failed; 113 114 composite_continue(result, creq, continue_resolve_name, result); 115 116 return result; 117 118 119 failed: 120 composite_error(result, result->status); 121 return result; 122 } 123 124 /* 125 start connecting to the next socket/port in the list 126 */ 127 static void connect_multi_next_socket(struct composite_context *result) 128 { 129 struct connect_multi_state *multi = talloc_get_type(result->private_data, 130 struct connect_multi_state); 131 struct connect_one_state *state; 132 struct composite_context *creq; 133 int next = multi->num_connects_sent; 134 135 if (next == multi->num_address * multi->num_ports) { 136 /* don't do anything, just wait for the existing ones to finish */ 137 return; 138 } 139 140 if (multi->current_address == multi->num_address) { 141 multi->current_address = 0; 142 multi->current_port += 1; 143 } 144 multi->num_connects_sent += 1; 145 146 if (multi->server_address == NULL || multi->server_address[multi->current_address] == NULL) { 147 composite_error(result, NT_STATUS_OBJECT_NAME_NOT_FOUND); 148 return; 149 } 150 151 state = talloc(multi, struct connect_one_state); 152 if (composite_nomem(state, result)) return; 153 154 state->result = result; 155 result->status = socket_create(multi->server_address[multi->current_address]->family, 156 SOCKET_TYPE_STREAM, &state->sock, 0); 157 if (!composite_is_ok(result)) return; 158 159 state->addr = socket_address_copy(state, multi->server_address[multi->current_address]); 160 if (composite_nomem(state->addr, result)) return; 161 162 socket_address_set_port(state->addr, multi->ports[multi->current_port]); 163 164 talloc_steal(state, state->sock); 165 166 creq = socket_connect_send(state->sock, NULL, 167 state->addr, 0, 168 result->event_ctx); 169 if (composite_nomem(creq, result)) return; 170 talloc_steal(state, creq); 171 172 multi->current_address++; 173 composite_continue(result, creq, continue_one, state); 174 175 /* if there are more ports / addresses to go then setup a timer to fire when we have waited 176 for a couple of milli-seconds, when that goes off we try the next port regardless 177 of whether this port has completed */ 178 if (multi->num_ports * multi->num_address > multi->num_connects_sent) { 179 /* note that this timer is a child of the single 180 connect attempt state, so it will go away when this 181 request completes */ 182 tevent_add_timer(result->event_ctx, state, 183 timeval_current_ofs_usec(MULTI_PORT_DELAY), 184 connect_multi_timer, result); 185 } 186 } 187 188 /* 189 a timer has gone off telling us that we should try the next port 190 */ 191 static void connect_multi_timer(struct tevent_context *ev, 192 struct tevent_timer *te, 193 struct timeval tv, void *p) 194 { 195 struct composite_context *result = talloc_get_type(p, struct composite_context); 196 connect_multi_next_socket(result); 197 } 198 199 200 /* 201 recv name resolution reply then send the next connect 202 */ 203 static void continue_resolve_name(struct composite_context *creq) 204 { 205 struct composite_context *result = talloc_get_type(creq->async.private_data, 206 struct composite_context); 207 struct connect_multi_state *multi = talloc_get_type(result->private_data, 208 struct connect_multi_state); 209 struct socket_address **addr; 210 unsigned i; 211 212 result->status = resolve_name_all_recv(creq, multi, &addr, NULL); 213 if (!composite_is_ok(result)) return; 214 215 for(i=0; addr[i]; i++); 216 multi->num_address = i; 217 multi->server_address = talloc_steal(multi, addr); 218 219 connect_multi_next_socket(result); 220 } 221 222 /* 223 one of our socket_connect_send() calls hash finished. If it got a 224 connection or there are none left then we are done 225 */ 226 static void continue_one(struct composite_context *creq) 227 { 228 struct connect_one_state *state = talloc_get_type(creq->async.private_data, 229 struct connect_one_state); 230 struct composite_context *result = state->result; 231 struct connect_multi_state *multi = talloc_get_type(result->private_data, 232 struct connect_multi_state); 233 NTSTATUS status; 234 235 status = socket_connect_recv(creq); 236 237 if (multi->ex) { 238 struct tevent_req *subreq; 239 240 subreq = multi->ex->establish_send(state, 241 result->event_ctx, 242 state->sock, 243 state->addr, 244 multi->ex->private_data); 245 if (composite_nomem(subreq, result)) return; 246 tevent_req_set_callback(subreq, continue_one_ex, state); 247 return; 248 } 249 250 multi->num_connects_recv++; 251 252 if (NT_STATUS_IS_OK(status)) { 253 multi->sock = talloc_steal(multi, state->sock); 254 multi->result_port = state->addr->port; 255 } 256 257 talloc_free(state); 258 259 if (NT_STATUS_IS_OK(status) || 260 multi->num_connects_recv == (multi->num_address * multi->num_ports)) { 261 result->status = status; 262 composite_done(result); 263 return; 264 } 265 266 /* try the next port */ 267 connect_multi_next_socket(result); 268 } 269 270 /* 271 one of our multi->ex->establish_send() calls hash finished. If it got a 272 connection or there are none left then we are done 273 */ 274 static void continue_one_ex(struct tevent_req *subreq) 275 { 276 struct connect_one_state *state = 277 tevent_req_callback_data(subreq, 278 struct connect_one_state); 279 struct composite_context *result = state->result; 280 struct connect_multi_state *multi = 281 talloc_get_type_abort(result->private_data, 282 struct connect_multi_state); 283 NTSTATUS status; 284 multi->num_connects_recv++; 285 286 status = multi->ex->establish_recv(subreq); 287 TALLOC_FREE(subreq); 288 289 if (NT_STATUS_IS_OK(status)) { 290 multi->sock = talloc_steal(multi, state->sock); 291 multi->result_port = state->addr->port; 292 } 293 294 talloc_free(state); 295 296 if (NT_STATUS_IS_OK(status) || 297 multi->num_connects_recv == (multi->num_address * multi->num_ports)) { 298 result->status = status; 299 composite_done(result); 300 return; 301 } 302 303 /* try the next port */ 304 connect_multi_next_socket(result); 305 } 306 307 /* 308 async recv routine for socket_connect_multi() 309 */ 310 _PUBLIC_ NTSTATUS socket_connect_multi_ex_recv(struct composite_context *ctx, 311 TALLOC_CTX *mem_ctx, 312 struct socket_context **sock, 313 uint16_t *port) 314 { 315 NTSTATUS status = composite_wait(ctx); 316 if (NT_STATUS_IS_OK(status)) { 317 struct connect_multi_state *multi = 318 talloc_get_type(ctx->private_data, 319 struct connect_multi_state); 320 *sock = talloc_steal(mem_ctx, multi->sock); 321 *port = multi->result_port; 322 } 323 talloc_free(ctx); 324 return status; 325 } 326 327 NTSTATUS socket_connect_multi_ex(TALLOC_CTX *mem_ctx, 328 const char *server_address, 329 int num_server_ports, uint16_t *server_ports, 330 struct resolve_context *resolve_ctx, 331 struct tevent_context *event_ctx, 332 struct socket_connect_multi_ex *ex, 333 struct socket_context **result, 334 uint16_t *result_port) 335 { 336 struct composite_context *ctx = 337 socket_connect_multi_ex_send(mem_ctx, server_address, 338 num_server_ports, server_ports, 339 resolve_ctx, 340 event_ctx, 341 ex); 342 return socket_connect_multi_ex_recv(ctx, mem_ctx, result, result_port); 343 } 61 344 62 345 /* … … 71 354 struct tevent_context *event_ctx) 72 355 { 73 struct composite_context *result; 74 struct connect_multi_state *multi; 75 int i; 76 77 struct nbt_name name; 78 struct composite_context *creq; 79 80 result = talloc_zero(mem_ctx, struct composite_context); 81 if (result == NULL) return NULL; 82 result->state = COMPOSITE_STATE_IN_PROGRESS; 83 result->event_ctx = event_ctx; 84 85 multi = talloc_zero(result, struct connect_multi_state); 86 if (composite_nomem(multi, result)) goto failed; 87 result->private_data = multi; 88 89 multi->num_ports = num_server_ports; 90 multi->ports = talloc_array(multi, uint16_t, multi->num_ports); 91 if (composite_nomem(multi->ports, result)) goto failed; 92 93 for (i=0; i<multi->num_ports; i++) { 94 multi->ports[i] = server_ports[i]; 95 } 96 97 /* 98 we don't want to do the name resolution separately 99 for each port, so start it now, then only start on 100 the real sockets once we have an IP 101 */ 102 make_nbt_name_server(&name, server_name); 103 104 creq = resolve_name_all_send(resolve_ctx, multi, 0, multi->ports[0], &name, result->event_ctx); 105 if (composite_nomem(creq, result)) goto failed; 106 107 composite_continue(result, creq, continue_resolve_name, result); 108 109 return result; 110 111 112 failed: 113 composite_error(result, result->status); 114 return result; 115 } 116 117 /* 118 start connecting to the next socket/port in the list 119 */ 120 static void connect_multi_next_socket(struct composite_context *result) 121 { 122 struct connect_multi_state *multi = talloc_get_type(result->private_data, 123 struct connect_multi_state); 124 struct connect_one_state *state; 125 struct composite_context *creq; 126 int next = multi->num_connects_sent; 127 128 if (next == multi->num_ports) { 129 /* don't do anything, just wait for the existing ones to finish */ 130 return; 131 } 132 133 multi->num_connects_sent += 1; 134 135 state = talloc(multi, struct connect_one_state); 136 if (composite_nomem(state, result)) return; 137 138 state->result = result; 139 result->status = socket_create("ipv4", SOCKET_TYPE_STREAM, &state->sock, 0); 140 if (!composite_is_ok(result)) return; 141 142 state->addr = socket_address_copy(state, multi->server_address); 143 if (composite_nomem(state->addr, result)) return; 144 145 socket_address_set_port(state->addr, multi->ports[next]); 146 147 talloc_steal(state, state->sock); 148 149 creq = socket_connect_send(state->sock, NULL, 150 state->addr, 0, 151 result->event_ctx); 152 if (composite_nomem(creq, result)) return; 153 talloc_steal(state, creq); 154 155 composite_continue(result, creq, continue_one, state); 156 157 /* if there are more ports to go then setup a timer to fire when we have waited 158 for a couple of milli-seconds, when that goes off we try the next port regardless 159 of whether this port has completed */ 160 if (multi->num_ports > multi->num_connects_sent) { 161 /* note that this timer is a child of the single 162 connect attempt state, so it will go away when this 163 request completes */ 164 event_add_timed(result->event_ctx, state, 165 timeval_current_ofs(0, MULTI_PORT_DELAY), 166 connect_multi_timer, result); 167 } 168 } 169 170 /* 171 a timer has gone off telling us that we should try the next port 172 */ 173 static void connect_multi_timer(struct tevent_context *ev, 174 struct tevent_timer *te, 175 struct timeval tv, void *p) 176 { 177 struct composite_context *result = talloc_get_type(p, struct composite_context); 178 connect_multi_next_socket(result); 179 } 180 181 182 /* 183 recv name resolution reply then send the next connect 184 */ 185 static void continue_resolve_name(struct composite_context *creq) 186 { 187 struct composite_context *result = talloc_get_type(creq->async.private_data, 188 struct composite_context); 189 struct connect_multi_state *multi = talloc_get_type(result->private_data, 190 struct connect_multi_state); 191 struct socket_address **addr; 192 193 result->status = resolve_name_all_recv(creq, multi, &addr, NULL); 194 if (!composite_is_ok(result)) return; 195 196 /* Let's just go for the first for now */ 197 multi->server_address = addr[0]; 198 199 connect_multi_next_socket(result); 200 } 201 202 /* 203 one of our socket_connect_send() calls hash finished. If it got a 204 connection or there are none left then we are done 205 */ 206 static void continue_one(struct composite_context *creq) 207 { 208 struct connect_one_state *state = talloc_get_type(creq->async.private_data, 209 struct connect_one_state); 210 struct composite_context *result = state->result; 211 struct connect_multi_state *multi = talloc_get_type(result->private_data, 212 struct connect_multi_state); 213 NTSTATUS status; 214 multi->num_connects_recv++; 215 216 status = socket_connect_recv(creq); 217 218 if (NT_STATUS_IS_OK(status)) { 219 multi->sock = talloc_steal(multi, state->sock); 220 multi->result_port = state->addr->port; 221 } 222 223 talloc_free(state); 224 225 if (NT_STATUS_IS_OK(status) || 226 multi->num_connects_recv == multi->num_ports) { 227 result->status = status; 228 composite_done(result); 229 return; 230 } 231 232 /* try the next port */ 233 connect_multi_next_socket(result); 356 return socket_connect_multi_ex_send(mem_ctx, 357 server_name, 358 num_server_ports, 359 server_ports, 360 resolve_ctx, 361 event_ctx, 362 NULL); /* ex */ 234 363 } 235 364 … … 242 371 uint16_t *port) 243 372 { 244 NTSTATUS status = composite_wait(ctx); 245 if (NT_STATUS_IS_OK(status)) { 246 struct connect_multi_state *multi = 247 talloc_get_type(ctx->private_data, 248 struct connect_multi_state); 249 *sock = talloc_steal(mem_ctx, multi->sock); 250 *port = multi->result_port; 251 } 252 talloc_free(ctx); 253 return status; 373 return socket_connect_multi_ex_recv(ctx, mem_ctx, sock, port); 254 374 } 255 375 … … 262 382 uint16_t *result_port) 263 383 { 264 struct composite_context *ctx = 265 socket_connect_multi_send(mem_ctx, server_address, 266 num_server_ports, server_ports, 267 resolve_ctx, 268 event_ctx); 269 return socket_connect_multi_recv(ctx, mem_ctx, result, result_port); 270 } 384 return socket_connect_multi_ex(mem_ctx, 385 server_address, 386 num_server_ports, 387 server_ports, 388 resolve_ctx, 389 event_ctx, 390 NULL, /* ex */ 391 result, 392 result_port); 393 } -
vendor/current/source4/lib/socket/interface.c
r740 r988 22 22 #include "includes.h" 23 23 #include "system/network.h" 24 #include "param/param.h" 24 25 #include "lib/socket/netif.h" 25 26 #include "../lib/util/util_net.h" 26 27 #include "../lib/util/dlinklist.h" 27 28 28 /* *used for network interfaces */29 /* used for network interfaces */ 29 30 struct interface { 30 31 struct interface *next, *prev; 31 struct in_addr ip; 32 struct in_addr nmask; 32 char *name; 33 int flags; 34 struct sockaddr_storage ip; 35 struct sockaddr_storage netmask; 36 struct sockaddr_storage bcast; 33 37 const char *ip_s; 34 38 const char *bcast_s; … … 46 50 Try and find an interface that matches an ip. If we cannot, return NULL 47 51 **************************************************************************/ 48 static struct interface *iface_find(struct interface *interfaces, 49 struct in_addr ip, bool CheckMask) 50 { 51 struct interface *i; 52 if (is_zero_ip_v4(ip)) return interfaces; 53 54 for (i=interfaces;i;i=i->next) 55 if (CheckMask) { 56 if (same_net_v4(i->ip,ip,i->nmask)) return i; 57 } else if (i->ip.s_addr == ip.s_addr) return i; 52 static struct interface *iface_list_find(struct interface *interfaces, 53 const struct sockaddr *ip, 54 bool check_mask) 55 { 56 struct interface *i; 57 58 if (is_address_any(ip)) { 59 return interfaces; 60 } 61 62 for (i=interfaces;i;i=i->next) { 63 if (check_mask) { 64 if (same_net(ip, (struct sockaddr *)&i->ip, (struct sockaddr *)&i->netmask)) { 65 return i; 66 } 67 } else if (sockaddr_equal((struct sockaddr *)&i->ip, ip)) { 68 return i; 69 } 70 } 58 71 59 72 return NULL; 60 73 } 61 62 74 63 75 /**************************************************************************** 64 76 add an interface to the linked list of interfaces 65 77 ****************************************************************************/ 66 static void add_interface(TALLOC_CTX *mem_ctx, struct in_addr ip, struct in_addr nmask, struct interface **interfaces) 67 { 78 static void add_interface(TALLOC_CTX *mem_ctx, const struct iface_struct *ifs, struct interface **interfaces, 79 bool enable_ipv6) 80 { 81 char addr[INET6_ADDRSTRLEN]; 68 82 struct interface *iface; 69 struct in_addr bcast; 70 71 if (iface_find(*interfaces, ip, false)) { 72 DEBUG(3,("not adding duplicate interface %s\n",inet_ntoa(ip))); 83 84 if (iface_list_find(*interfaces, (const struct sockaddr *)&ifs->ip, false)) { 85 DEBUG(3,("add_interface: not adding duplicate interface %s\n", 86 print_sockaddr(addr, sizeof(addr), &ifs->ip) )); 87 return; 88 } 89 90 if (ifs->ip.ss_family == AF_INET && 91 !(ifs->flags & (IFF_BROADCAST|IFF_LOOPBACK))) { 92 DEBUG(3,("not adding non-broadcast interface %s\n", 93 ifs->name )); 94 return; 95 } 96 97 if (!enable_ipv6 && ifs->ip.ss_family != AF_INET) { 73 98 return; 74 99 } … … 80 105 ZERO_STRUCTPN(iface); 81 106 82 iface->ip = ip; 83 iface->nmask = nmask; 84 bcast.s_addr = MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr); 107 iface->name = talloc_strdup(iface, ifs->name); 108 if (!iface->name) { 109 SAFE_FREE(iface); 110 return; 111 } 112 iface->flags = ifs->flags; 113 iface->ip = ifs->ip; 114 iface->netmask = ifs->netmask; 115 iface->bcast = ifs->bcast; 85 116 86 117 /* keep string versions too, to avoid people tripping over the implied 87 118 static in inet_ntoa() */ 88 iface->ip_s = talloc_strdup(iface, inet_ntoa(iface->ip)); 89 iface->nmask_s = talloc_strdup(iface, inet_ntoa(iface->nmask)); 90 91 if (nmask.s_addr != ~0) { 92 iface->bcast_s = talloc_strdup(iface, inet_ntoa(bcast)); 93 } 94 95 DLIST_ADD_END(*interfaces, iface, struct interface *); 96 97 DEBUG(3,("added interface ip=%s nmask=%s\n", iface->ip_s, iface->nmask_s)); 98 } 99 100 119 print_sockaddr(addr, sizeof(addr), &iface->ip); 120 DEBUG(4,("added interface %s ip=%s ", 121 iface->name, addr)); 122 iface->ip_s = talloc_strdup(iface, addr); 123 124 print_sockaddr(addr, sizeof(addr), 125 &iface->bcast); 126 DEBUG(4,("bcast=%s ", addr)); 127 iface->bcast_s = talloc_strdup(iface, addr); 128 129 print_sockaddr(addr, sizeof(addr), 130 &iface->netmask); 131 DEBUG(4,("netmask=%s\n", addr)); 132 iface->nmask_s = talloc_strdup(iface, addr); 133 134 /* 135 this needs to be a ADD_END, as some tests (such as the 136 spoolss notify test) depend on the interfaces ordering 137 */ 138 DLIST_ADD_END(*interfaces, iface); 139 } 101 140 102 141 /** … … 115 154 struct iface_struct *probed_ifaces, 116 155 int total_probed, 117 struct interface **local_interfaces) 118 { 119 struct in_addr ip, nmask; 156 struct interface **local_interfaces, 157 bool enable_ipv6) 158 { 159 struct sockaddr_storage ss; 160 struct sockaddr_storage ss_mask; 161 struct sockaddr_storage ss_net; 162 struct sockaddr_storage ss_bcast; 163 struct iface_struct ifs; 120 164 char *p; 121 char *address; 122 int i, added=0; 123 124 ip.s_addr = 0; 125 nmask.s_addr = 0; 126 165 int i; 166 bool added=false; 167 bool goodaddr = false; 168 127 169 /* first check if it is an interface name */ 128 170 for (i=0;i<total_probed;i++) { 129 171 if (gen_fnmatch(token, probed_ifaces[i].name) == 0) { 130 add_interface(mem_ctx, probed_ifaces[i].ip, 131 probed_ifaces[i].netmask, 132 local_interfaces); 133 added = 1; 134 } 135 } 136 if (added) return; 172 add_interface(mem_ctx, &probed_ifaces[i], 173 local_interfaces, enable_ipv6); 174 added = true; 175 } 176 } 177 if (added) { 178 return; 179 } 180 181 p = strchr_m(token, ';'); 182 if (p != NULL) { 183 /* 184 * skip smbd-specific extra data: 185 * link speed, capabilities, and interface index 186 */ 187 *p = 0; 188 } 137 189 138 190 /* maybe it is a DNS name */ 139 191 p = strchr_m(token,'/'); 140 if (!p) { 141 /* don't try to do dns lookups on wildcard names */ 142 if (strpbrk(token, "*?") != NULL) { 192 if (p == NULL) { 193 if (!interpret_string_addr(&ss, token, 0)) { 194 DEBUG(2, ("interpret_interface: Can't find address " 195 "for %s\n", token)); 143 196 return; 144 197 } 145 ip.s_addr = interpret_addr2(token).s_addr; 198 146 199 for (i=0;i<total_probed;i++) { 147 if (ip.s_addr == probed_ifaces[i].ip.s_addr) { 148 add_interface(mem_ctx, probed_ifaces[i].ip, 149 probed_ifaces[i].netmask, 150 local_interfaces); 200 if (sockaddr_equal((struct sockaddr *)&ss, (struct sockaddr *)&probed_ifaces[i].ip)) { 201 add_interface(mem_ctx, &probed_ifaces[i], 202 local_interfaces, enable_ipv6); 151 203 return; 152 204 } 153 205 } 154 DEBUG(2,("can't determine netmask for %s\n", token)); 155 return; 156 } 157 158 address = talloc_strdup(mem_ctx, token); 159 p = strchr_m(address,'/'); 206 DEBUG(2,("interpret_interface: " 207 "can't determine interface for %s\n", 208 token)); 209 return; 210 } 160 211 161 212 /* parse it into an IP address/netmasklength pair */ 162 *p++ = 0; 163 164 ip.s_addr = interpret_addr2(address).s_addr; 213 *p = 0; 214 goodaddr = interpret_string_addr(&ss, token, 0); 215 *p++ = '/'; 216 217 if (!goodaddr) { 218 DEBUG(2,("interpret_interface: " 219 "can't determine interface for %s\n", 220 token)); 221 return; 222 } 165 223 166 224 if (strlen(p) > 2) { 167 nmask.s_addr = interpret_addr2(p).s_addr; 225 goodaddr = interpret_string_addr(&ss_mask, p, 0); 226 if (!goodaddr) { 227 DEBUG(2,("interpret_interface: " 228 "can't determine netmask from %s\n", 229 p)); 230 return; 231 } 168 232 } else { 169 nmask.s_addr = htonl(((ALLONES >> atoi(p)) ^ ALLONES)); 170 } 171 172 /* maybe the first component was a broadcast address */ 173 if (ip.s_addr == MKBCADDR(ip.s_addr, nmask.s_addr) || 174 ip.s_addr == MKNETADDR(ip.s_addr, nmask.s_addr)) { 233 char *endp = NULL; 234 unsigned long val = strtoul(p, &endp, 0); 235 if (p == endp || (endp && *endp != '\0')) { 236 DEBUG(2,("interpret_interface: " 237 "can't determine netmask value from %s\n", 238 p)); 239 return; 240 } 241 if (!make_netmask(&ss_mask, &ss, val)) { 242 DEBUG(2,("interpret_interface: " 243 "can't apply netmask value %lu from %s\n", 244 val, 245 p)); 246 return; 247 } 248 } 249 250 make_bcast(&ss_bcast, &ss, &ss_mask); 251 make_net(&ss_net, &ss, &ss_mask); 252 253 /* Maybe the first component was a broadcast address. */ 254 if (sockaddr_equal((struct sockaddr *)&ss_bcast, (struct sockaddr *)&ss) || 255 sockaddr_equal((struct sockaddr *)&ss_net, (struct sockaddr *)&ss)) { 175 256 for (i=0;i<total_probed;i++) { 176 if (same_net_v4(ip, probed_ifaces[i].ip, nmask)) { 177 add_interface(mem_ctx, probed_ifaces[i].ip, nmask, 178 local_interfaces); 179 talloc_free(address); 257 if (same_net((struct sockaddr *)&ss, 258 (struct sockaddr *)&probed_ifaces[i].ip, 259 (struct sockaddr *)&ss_mask)) { 260 /* Temporarily replace netmask on 261 * the detected interface - user knows 262 * best.... */ 263 struct sockaddr_storage saved_mask = 264 probed_ifaces[i].netmask; 265 probed_ifaces[i].netmask = ss_mask; 266 DEBUG(2,("interpret_interface: " 267 "using netmask value %s from " 268 "config file on interface %s\n", 269 p, 270 probed_ifaces[i].name)); 271 add_interface(mem_ctx, &probed_ifaces[i], 272 local_interfaces, enable_ipv6); 273 probed_ifaces[i].netmask = saved_mask; 180 274 return; 181 275 } 182 276 } 183 DEBUG(2,("Can't determine ip for broadcast address %s\n", address)); 184 talloc_free(address); 185 return; 186 } 187 188 add_interface(mem_ctx, ip, nmask, local_interfaces); 189 talloc_free(address); 277 DEBUG(2,("interpret_interface: Can't determine ip for " 278 "broadcast address %s\n", 279 token)); 280 return; 281 } 282 283 /* Just fake up the interface definition. User knows best. */ 284 285 DEBUG(2,("interpret_interface: Adding interface %s\n", 286 token)); 287 288 ZERO_STRUCT(ifs); 289 (void)strlcpy(ifs.name, token, sizeof(ifs.name)); 290 ifs.flags = IFF_BROADCAST; 291 ifs.ip = ss; 292 ifs.netmask = ss_mask; 293 ifs.bcast = ss_bcast; 294 add_interface(mem_ctx, &ifs, 295 local_interfaces, enable_ipv6); 190 296 } 191 297 … … 194 300 load the list of network interfaces 195 301 **/ 196 void load_interface s(TALLOC_CTX *mem_ctx, const char **interfaces, struct interface **local_interfaces)197 { 198 const char **ptr = interfaces;302 void load_interface_list(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct interface **local_interfaces) 303 { 304 const char **ptr = lpcfg_interfaces(lp_ctx); 199 305 int i; 200 struct iface_struct ifaces[MAX_INTERFACES]; 201 struct in_addr loopback_ip; 306 struct iface_struct *ifaces = NULL; 202 307 int total_probed; 308 bool enable_ipv6 = lpcfg_parm_bool(lp_ctx, NULL, "ipv6", "enable", true); 203 309 204 310 *local_interfaces = NULL; 205 311 206 loopback_ip = interpret_addr2("127.0.0.1");207 208 312 /* probe the kernel for interfaces */ 209 total_probed = get_interfaces( ifaces, MAX_INTERFACES);313 total_probed = get_interfaces(mem_ctx, &ifaces); 210 314 211 315 /* if we don't have a interfaces line then use all interfaces … … 216 320 } 217 321 for (i=0;i<total_probed;i++) { 218 if (ifaces[i].ip.s_addr != loopback_ip.s_addr) { 219 add_interface(mem_ctx, ifaces[i].ip, 220 ifaces[i].netmask, local_interfaces); 322 if (!is_loopback_addr((struct sockaddr *)&ifaces[i].ip)) { 323 add_interface(mem_ctx, &ifaces[i], local_interfaces, enable_ipv6); 221 324 } 222 325 } … … 224 327 225 328 while (ptr && *ptr) { 226 interpret_interface(mem_ctx, *ptr, ifaces, total_probed, local_interfaces );329 interpret_interface(mem_ctx, *ptr, ifaces, total_probed, local_interfaces, enable_ipv6); 227 330 ptr++; 228 331 } … … 231 334 DEBUG(0,("WARNING: no network interfaces found\n")); 232 335 } 336 talloc_free(ifaces); 233 337 } 234 338 … … 236 340 how many interfaces do we have 237 341 **/ 238 int iface_ count(struct interface *ifaces)342 int iface_list_count(struct interface *ifaces) 239 343 { 240 344 int ret = 0; … … 249 353 return IP of the Nth interface 250 354 **/ 251 const char *iface_ n_ip(struct interface *ifaces, int n)355 const char *iface_list_n_ip(struct interface *ifaces, int n) 252 356 { 253 357 struct interface *i; … … 262 366 } 263 367 368 369 /** 370 return the first IPv4 interface address we have registered 371 **/ 372 const char *iface_list_first_v4(struct interface *ifaces) 373 { 374 struct interface *i; 375 376 for (i=ifaces; i; i=i->next) { 377 if (i->ip.ss_family == AF_INET) { 378 return i->ip_s; 379 } 380 } 381 return NULL; 382 } 383 384 /** 385 return the first IPv6 interface address we have registered 386 **/ 387 static const char *iface_list_first_v6(struct interface *ifaces) 388 { 389 struct interface *i; 390 391 #ifdef HAVE_IPV6 392 for (i=ifaces; i; i=i->next) { 393 if (i->ip.ss_family == AF_INET6) { 394 return i->ip_s; 395 } 396 } 397 #endif 398 return NULL; 399 } 400 401 /** 402 check if an interface is IPv4 403 **/ 404 bool iface_list_n_is_v4(struct interface *ifaces, int n) 405 { 406 struct interface *i; 407 408 for (i=ifaces;i && n;i=i->next) 409 n--; 410 411 if (i) { 412 return i->ip.ss_family == AF_INET; 413 } 414 return false; 415 } 416 264 417 /** 265 418 return bcast of the Nth interface 266 419 **/ 267 const char *iface_ n_bcast(struct interface *ifaces, int n)420 const char *iface_list_n_bcast(struct interface *ifaces, int n) 268 421 { 269 422 struct interface *i; … … 281 434 return netmask of the Nth interface 282 435 **/ 283 const char *iface_ n_netmask(struct interface *ifaces, int n)436 const char *iface_list_n_netmask(struct interface *ifaces, int n) 284 437 { 285 438 struct interface *i; … … 298 451 our first interface if none match 299 452 */ 300 const char *iface_ best_ip(struct interface *ifaces, const char *dest)453 const char *iface_list_best_ip(struct interface *ifaces, const char *dest) 301 454 { 302 455 struct interface *iface; 303 struct in_addr ip; 304 305 ip.s_addr = interpret_addr(dest); 306 iface = iface_find(ifaces, ip, true); 456 struct sockaddr_storage ss; 457 458 if (!interpret_string_addr(&ss, dest, AI_NUMERICHOST)) { 459 return iface_list_n_ip(ifaces, 0); 460 } 461 iface = iface_list_find(ifaces, (const struct sockaddr *)&ss, true); 307 462 if (iface) { 308 463 return iface->ip_s; 309 464 } 310 return iface_n_ip(ifaces, 0); 465 #ifdef HAVE_IPV6 466 if (ss.ss_family == AF_INET6) { 467 return iface_list_first_v6(ifaces); 468 } 469 #endif 470 return iface_list_first_v4(ifaces); 311 471 } 312 472 … … 314 474 return true if an IP is one one of our local networks 315 475 */ 316 bool iface_is_local(struct interface *ifaces, const char *dest) 317 { 318 struct in_addr ip; 319 320 ip.s_addr = interpret_addr(dest); 321 if (iface_find(ifaces, ip, true)) { 476 bool iface_list_is_local(struct interface *ifaces, const char *dest) 477 { 478 struct sockaddr_storage ss; 479 480 if (!interpret_string_addr(&ss, dest, AI_NUMERICHOST)) { 481 return false; 482 } 483 if (iface_list_find(ifaces, (const struct sockaddr *)&ss, true)) { 322 484 return true; 323 485 } … … 328 490 return true if a IP matches a IP/netmask pair 329 491 */ 330 bool iface_same_net(const char *ip1, const char *ip2, const char *netmask) 331 { 332 return same_net_v4(interpret_addr2(ip1), 333 interpret_addr2(ip2), 334 interpret_addr2(netmask)); 335 } 492 bool iface_list_same_net(const char *ip1, const char *ip2, const char *netmask) 493 { 494 struct sockaddr_storage ip1_ss, ip2_ss, nm_ss; 495 496 if (!interpret_string_addr(&ip1_ss, ip1, AI_NUMERICHOST)) { 497 return false; 498 } 499 if (!interpret_string_addr(&ip2_ss, ip2, AI_NUMERICHOST)) { 500 return false; 501 } 502 if (!interpret_string_addr(&nm_ss, netmask, AI_NUMERICHOST)) { 503 return false; 504 } 505 506 return same_net((struct sockaddr *)&ip1_ss, 507 (struct sockaddr *)&ip2_ss, 508 (struct sockaddr *)&nm_ss); 509 } 510 511 /** 512 return the list of wildcard interfaces 513 this will include the IPv4 0.0.0.0, and may include IPv6 :: 514 */ 515 char **iface_list_wildcard(TALLOC_CTX *mem_ctx) 516 { 517 char **ret; 518 #ifdef HAVE_IPV6 519 ret = str_list_make(mem_ctx, "::,0.0.0.0", NULL); 520 #else 521 ret = str_list_make(mem_ctx, "0.0.0.0", NULL); 522 #endif 523 return ret; 524 } -
vendor/current/source4/lib/socket/netif.h
r414 r988 21 21 22 22 #include "system/network.h" 23 24 struct iface_struct { 25 char name[16]; 26 struct in_addr ip; 27 struct in_addr netmask; 28 }; 29 30 struct interface; 31 32 #define MAX_INTERFACES 128 33 34 #ifndef AUTOCONF_TEST 23 #include "lib/socket/interfaces.h" 35 24 #include "lib/socket/netif_proto.h" 36 #endif -
vendor/current/source4/lib/socket/socket.c
r740 r988 353 353 int ret; 354 354 355 if (!a) { 356 return NULL; 357 } 355 358 if (a->sockaddr) { 356 359 ret = tsocket_address_bsd_from_sockaddr(mem_ctx, … … 452 455 fd = dup(sock->fd); 453 456 if (fd == -1) { 454 return map_nt_error_from_unix (errno);457 return map_nt_error_from_unix_common(errno); 455 458 } 456 459 close(sock->fd); … … 474 477 } 475 478 479 if (strcmp(family, "ip") == 0 && is_ipaddress_v6(host)) { 480 /* leaving as "ip" would force IPv4 */ 481 family = "ipv6"; 482 } 483 476 484 addr->family = family; 477 485 addr->addr = talloc_strdup(addr, host); … … 499 507 return NULL; 500 508 } 501 addr->family = NULL; 509 switch (sockaddr->sa_family) { 510 case AF_INET: 511 addr->family = "ipv4"; 512 break; 513 #ifdef HAVE_IPV6 514 case AF_INET6: 515 addr->family = "ipv6"; 516 break; 517 #endif 518 case AF_UNIX: 519 addr->family = "unix"; 520 break; 521 } 502 522 addr->addr = NULL; 503 523 addr->port = 0; … … 508 528 } 509 529 addr->sockaddrlen = sockaddrlen; 530 return addr; 531 } 532 533 534 /* 535 Create a new socket_address from sockaddr_storage 536 */ 537 _PUBLIC_ struct socket_address *socket_address_from_sockaddr_storage(TALLOC_CTX *mem_ctx, 538 const struct sockaddr_storage *sockaddr, 539 uint16_t port) 540 { 541 struct socket_address *addr = talloc_zero(mem_ctx, struct socket_address); 542 char addr_str[INET6_ADDRSTRLEN+1]; 543 const char *str; 544 545 if (!addr) { 546 return NULL; 547 } 548 addr->port = port; 549 switch (sockaddr->ss_family) { 550 case AF_INET: 551 addr->family = "ipv4"; 552 break; 553 #ifdef HAVE_IPV6 554 case AF_INET6: 555 addr->family = "ipv6"; 556 break; 557 #endif 558 default: 559 talloc_free(addr); 560 return NULL; 561 } 562 563 str = print_sockaddr(addr_str, sizeof(addr_str), sockaddr); 564 if (str == NULL) { 565 talloc_free(addr); 566 return NULL; 567 } 568 addr->addr = talloc_strdup(addr, str); 569 if (addr->addr == NULL) { 570 talloc_free(addr); 571 return NULL; 572 } 573 510 574 return addr; 511 575 } … … 568 632 } 569 633 570 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};571 572 static const struct {573 const char *name;574 int level;575 int option;576 int value;577 int opttype;578 } socket_options[] = {579 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},580 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},581 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},582 #ifdef TCP_NODELAY583 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},584 #endif585 #ifdef IPTOS_LOWDELAY586 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},587 #endif588 #ifdef IPTOS_THROUGHPUT589 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},590 #endif591 #ifdef SO_REUSEPORT592 {"SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, 0, OPT_BOOL},593 #endif594 #ifdef SO_SNDBUF595 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},596 #endif597 #ifdef SO_RCVBUF598 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},599 #endif600 #ifdef SO_SNDLOWAT601 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},602 #endif603 #ifdef SO_RCVLOWAT604 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},605 #endif606 #ifdef SO_SNDTIMEO607 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},608 #endif609 #ifdef SO_RCVTIMEO610 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},611 #endif612 {NULL,0,0,0,0}};613 614 615 /**616 Set user socket options.617 **/618 _PUBLIC_ void set_socket_options(int fd, const char *options)619 {620 const char **options_list = (const char **)str_list_make(NULL, options, " \t,");621 int j;622 623 if (!options_list)624 return;625 626 for (j = 0; options_list[j]; j++) {627 const char *tok = options_list[j];628 int ret=0,i;629 int value = 1;630 char *p;631 bool got_value = false;632 633 if ((p = strchr(tok,'='))) {634 *p = 0;635 value = atoi(p+1);636 got_value = true;637 }638 639 for (i=0;socket_options[i].name;i++)640 if (strequal(socket_options[i].name,tok))641 break;642 643 if (!socket_options[i].name) {644 DEBUG(0,("Unknown socket option %s\n",tok));645 continue;646 }647 648 switch (socket_options[i].opttype) {649 case OPT_BOOL:650 case OPT_INT:651 ret = setsockopt(fd,socket_options[i].level,652 socket_options[i].option,(char *)&value,sizeof(int));653 break;654 655 case OPT_ON:656 if (got_value)657 DEBUG(0,("syntax error - %s does not take a value\n",tok));658 659 {660 int on = socket_options[i].value;661 ret = setsockopt(fd,socket_options[i].level,662 socket_options[i].option,(char *)&on,sizeof(int));663 }664 break;665 }666 667 if (ret != 0)668 DEBUG(0,("Failed to set socket option %s (Error %s)\n",tok, strerror(errno) ));669 }670 671 talloc_free(options_list);672 }673 674 634 /* 675 635 set some flags on a socket -
vendor/current/source4/lib/socket/socket.h
r740 r988 175 175 struct sockaddr *sockaddr, 176 176 size_t addrlen); 177 struct sockaddr_storage; 178 struct socket_address *socket_address_from_sockaddr_storage(TALLOC_CTX *mem_ctx, 179 const struct sockaddr_storage *sockaddr, 180 uint16_t port); 177 181 _PUBLIC_ void socket_address_set_port(struct socket_address *a, 178 182 uint16_t port); … … 180 184 const struct socket_address *oaddr); 181 185 const struct socket_ops *socket_getops_byname(const char *name, enum socket_type type); 182 bool allow_access(TALLOC_CTX *mem_ctx,183 184 186 bool socket_allow_access(TALLOC_CTX *mem_ctx, 187 const char **deny_list, const char **allow_list, 188 const char *cname, const char *caddr); 185 189 bool socket_check_access(struct socket_context *sock, 186 190 const char *service_name, … … 198 202 uint32_t flags, 199 203 struct tevent_context *ev); 204 205 struct socket_connect_multi_ex { 206 void *private_data; 207 struct tevent_req *(*establish_send)(TALLOC_CTX *mem_ctx, 208 struct tevent_context *ev, 209 struct socket_context *sock, 210 struct socket_address *addr, 211 void *private_data); 212 NTSTATUS (*establish_recv)(struct tevent_req *req); 213 }; 214 struct composite_context *socket_connect_multi_ex_send(TALLOC_CTX *mem_ctx, 215 const char *server_address, 216 int num_server_ports, 217 uint16_t *server_ports, 218 struct resolve_context *resolve_ctx, 219 struct tevent_context *event_ctx, 220 struct socket_connect_multi_ex *ex); 221 NTSTATUS socket_connect_multi_ex_recv(struct composite_context *ctx, 222 TALLOC_CTX *mem_ctx, 223 struct socket_context **result, 224 uint16_t *port); 225 NTSTATUS socket_connect_multi_ex(TALLOC_CTX *mem_ctx, const char *server_address, 226 int num_server_ports, uint16_t *server_ports, 227 struct resolve_context *resolve_ctx, 228 struct tevent_context *event_ctx, 229 struct socket_connect_multi_ex *ex, 230 struct socket_context **result, 231 uint16_t *port); 200 232 201 233 struct composite_context *socket_connect_multi_send(TALLOC_CTX *mem_ctx, -
vendor/current/source4/lib/socket/socket_ip.c
r740 r988 28 28 #include "lib/util/util_net.h" 29 29 30 _PUBLIC_ const struct socket_ops *socket_ipv4_ops(enum socket_type type); 31 _PUBLIC_ const struct socket_ops *socket_ipv6_ops(enum socket_type type); 32 30 33 static NTSTATUS ipv4_init(struct socket_context *sock) 31 34 { … … 45 48 sock->fd = socket(PF_INET, type, 0); 46 49 if (sock->fd == -1) { 47 return map_nt_error_from_unix(errno); 48 } 50 return map_nt_error_from_unix_common(errno); 51 } 52 53 smb_set_close_on_exec(sock->fd); 49 54 50 55 sock->backend_name = "ipv4"; … … 56 61 static void ip_close(struct socket_context *sock) 57 62 { 58 close(sock->fd); 63 if (sock->fd != -1) { 64 close(sock->fd); 65 sock->fd = -1; 66 } 59 67 } 60 68 … … 68 76 ret = getsockopt(sock->fd, SOL_SOCKET, SO_ERROR, &error, &len); 69 77 if (ret == -1) { 70 return map_nt_error_from_unix (errno);78 return map_nt_error_from_unix_common(errno); 71 79 } 72 80 if (error != 0) { 73 return map_nt_error_from_unix (error);81 return map_nt_error_from_unix_common(error); 74 82 } 75 83 … … 77 85 ret = set_blocking(sock->fd, false); 78 86 if (ret == -1) { 79 return map_nt_error_from_unix (errno);87 return map_nt_error_from_unix_common(errno); 80 88 } 81 89 } … … 100 108 ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen); 101 109 if (ret == -1) { 102 return map_nt_error_from_unix (errno);110 return map_nt_error_from_unix_common(errno); 103 111 } 104 112 } else if (my_address) { … … 117 125 ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); 118 126 if (ret == -1) { 119 return map_nt_error_from_unix (errno);127 return map_nt_error_from_unix_common(errno); 120 128 } 121 129 } … … 125 133 ret = connect(sock->fd, srv_address->sockaddr, srv_address->sockaddrlen); 126 134 if (ret == -1) { 127 return map_nt_error_from_unix (errno);135 return map_nt_error_from_unix_common(errno); 128 136 } 129 137 } else { … … 145 153 ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr)); 146 154 if (ret == -1) { 147 return map_nt_error_from_unix (errno);155 return map_nt_error_from_unix_common(errno); 148 156 } 149 157 } … … 184 192 185 193 if (ret == -1) { 186 return map_nt_error_from_unix (errno);194 return map_nt_error_from_unix_common(errno); 187 195 } 188 196 … … 190 198 ret = listen(sock->fd, queue_size); 191 199 if (ret == -1) { 192 return map_nt_error_from_unix (errno);200 return map_nt_error_from_unix_common(errno); 193 201 } 194 202 } … … 197 205 ret = set_blocking(sock->fd, false); 198 206 if (ret == -1) { 199 return map_nt_error_from_unix (errno);207 return map_nt_error_from_unix_common(errno); 200 208 } 201 209 } … … 218 226 new_fd = accept(sock->fd, (struct sockaddr *)&cli_addr, &cli_addr_len); 219 227 if (new_fd == -1) { 220 return map_nt_error_from_unix (errno);228 return map_nt_error_from_unix_common(errno); 221 229 } 222 230 … … 225 233 if (ret == -1) { 226 234 close(new_fd); 227 return map_nt_error_from_unix (errno);235 return map_nt_error_from_unix_common(errno); 228 236 } 229 237 } … … 266 274 return NT_STATUS_END_OF_FILE; 267 275 } else if (gotlen == -1) { 268 return map_nt_error_from_unix (errno);276 return map_nt_error_from_unix_common(errno); 269 277 } 270 278 … … 309 317 } else if (gotlen == -1) { 310 318 talloc_free(src); 311 return map_nt_error_from_unix (errno);319 return map_nt_error_from_unix_common(errno); 312 320 } 313 321 … … 340 348 len = send(sock->fd, blob->data, blob->length, 0); 341 349 if (len == -1) { 342 return map_nt_error_from_unix (errno);350 return map_nt_error_from_unix_common(errno); 343 351 } 344 352 … … 381 389 } 382 390 if (len == -1) { 383 return map_nt_error_from_unix (errno);391 return map_nt_error_from_unix_common(errno); 384 392 } 385 393 … … 516 524 return NT_STATUS_OK; 517 525 } 518 return map_nt_error_from_unix (errno);526 return map_nt_error_from_unix_common(errno); 519 527 } 520 528 … … 602 610 sock->fd = socket(PF_INET6, type, 0); 603 611 if (sock->fd == -1) { 604 return map_nt_error_from_unix(errno); 605 } 612 return map_nt_error_from_unix_common(errno); 613 } 614 615 smb_set_close_on_exec(sock->fd); 606 616 607 617 sock->backend_name = "ipv6"; … … 621 631 ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen); 622 632 if (ret == -1) { 623 return map_nt_error_from_unix (errno);633 return map_nt_error_from_unix_common(errno); 624 634 } 625 635 } else if (my_address) { … … 636 646 ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); 637 647 if (ret == -1) { 638 return map_nt_error_from_unix (errno);648 return map_nt_error_from_unix_common(errno); 639 649 } 640 650 } … … 659 669 } 660 670 if (ret == -1) { 661 return map_nt_error_from_unix (errno);671 return map_nt_error_from_unix_common(errno); 662 672 } 663 673 … … 665 675 } 666 676 677 /* 678 fix the sin6_scope_id based on the address interface 679 */ 680 static void fix_scope_id(struct sockaddr_in6 *in6, 681 const char *address) 682 { 683 const char *p = strchr(address, '%'); 684 if (p != NULL) { 685 in6->sin6_scope_id = if_nametoindex(p+1); 686 } 687 } 688 689 667 690 static NTSTATUS ipv6_listen(struct socket_context *sock, 668 669 691 const struct socket_address *my_address, 692 int queue_size, uint32_t flags) 670 693 { 671 694 struct sockaddr_in6 my_addr; … … 678 701 ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen); 679 702 } else { 703 int one = 1; 680 704 ip_addr = interpret_addr6(my_address->addr); 681 705 … … 684 708 my_addr.sin6_port = htons(my_address->port); 685 709 my_addr.sin6_family = PF_INET6; 686 687 ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); 710 fix_scope_id(&my_addr, my_address->addr); 711 712 /* when binding on ipv6 we always want to only bind on v6 */ 713 ret = setsockopt(sock->fd, IPPROTO_IPV6, IPV6_V6ONLY, 714 (const void *)&one, sizeof(one)); 715 if (ret != -1) { 716 ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); 717 } 688 718 } 689 719 690 720 if (ret == -1) { 691 return map_nt_error_from_unix (errno);721 return map_nt_error_from_unix_common(errno); 692 722 } 693 723 … … 695 725 ret = listen(sock->fd, queue_size); 696 726 if (ret == -1) { 697 return map_nt_error_from_unix (errno);727 return map_nt_error_from_unix_common(errno); 698 728 } 699 729 } … … 702 732 ret = set_blocking(sock->fd, false); 703 733 if (ret == -1) { 704 return map_nt_error_from_unix (errno);734 return map_nt_error_from_unix_common(errno); 705 735 } 706 736 } … … 723 753 new_fd = accept(sock->fd, (struct sockaddr *)&cli_addr, &cli_addr_len); 724 754 if (new_fd == -1) { 725 return map_nt_error_from_unix (errno);755 return map_nt_error_from_unix_common(errno); 726 756 } 727 757 … … 730 760 if (ret == -1) { 731 761 close(new_fd); 732 return map_nt_error_from_unix (errno);762 return map_nt_error_from_unix_common(errno); 733 763 } 734 764 } … … 794 824 } else if (gotlen == -1) { 795 825 talloc_free(src); 796 return map_nt_error_from_unix (errno);826 return map_nt_error_from_unix_common(errno); 797 827 } 798 828 … … 845 875 } 846 876 if (len == -1) { 847 return map_nt_error_from_unix (errno);877 return map_nt_error_from_unix_common(errno); 848 878 } 849 879 -
vendor/current/source4/lib/socket/socket_unix.c
r414 r988 26 26 #include "system/filesys.h" 27 27 28 _PUBLIC_ const struct socket_ops *socket_unixdom_ops(enum socket_type type); 28 29 29 30 … … 33 34 static NTSTATUS unixdom_error(int ernum) 34 35 { 35 return map_nt_error_from_unix (ernum);36 return map_nt_error_from_unix_common(ernum); 36 37 } 37 38 … … 53 54 sock->fd = socket(PF_UNIX, type, 0); 54 55 if (sock->fd == -1) { 55 return map_nt_error_from_unix (errno);56 return map_nt_error_from_unix_common(errno); 56 57 } 57 58 sock->private_data = NULL; 58 59 59 60 sock->backend_name = "unix"; 61 62 smb_set_close_on_exec(sock->fd); 60 63 61 64 return NT_STATUS_OK; … … 76 79 ret = getsockopt(sock->fd, SOL_SOCKET, SO_ERROR, &error, &len); 77 80 if (ret == -1) { 78 return map_nt_error_from_unix (errno);81 return map_nt_error_from_unix_common(errno); 79 82 } 80 83 if (error != 0) { 81 return map_nt_error_from_unix (error);84 return map_nt_error_from_unix_common(error); 82 85 } 83 86 … … 85 88 ret = set_blocking(sock->fd, false); 86 89 if (ret == -1) { 87 return map_nt_error_from_unix (errno);90 return map_nt_error_from_unix_common(errno); 88 91 } 89 92 } … … 111 114 ZERO_STRUCT(srv_addr); 112 115 srv_addr.sun_family = AF_UNIX; 113 s trncpy(srv_addr.sun_path, srv_address->addr, sizeof(srv_addr.sun_path));116 snprintf(srv_addr.sun_path, sizeof(srv_addr.sun_path), "%s", srv_address->addr); 114 117 115 118 ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr)); … … 146 149 ZERO_STRUCT(my_addr); 147 150 my_addr.sun_family = AF_UNIX; 148 s trncpy(my_addr.sun_path, my_address->addr, sizeof(my_addr.sun_path));149 151 snprintf(my_addr.sun_path, sizeof(my_addr.sun_path), "%s", my_address->addr); 152 150 153 ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); 151 154 } … … 194 197 if (ret == -1) { 195 198 close(new_fd); 196 return map_nt_error_from_unix(errno); 197 } 198 } 199 return map_nt_error_from_unix_common(errno); 200 } 201 } 202 203 smb_set_close_on_exec(new_fd); 199 204 200 205 (*new_sock) = talloc(NULL, struct socket_context); … … 259 264 const struct socket_address *dest) 260 265 { 266 struct sockaddr_un srv_addr; 267 const struct sockaddr *sa; 268 socklen_t sa_len; 261 269 ssize_t len; 270 262 271 *sendlen = 0; 263 272 264 273 if (dest->sockaddr) { 265 len = sendto(sock->fd, blob->data, blob->length, 0,266 dest->sockaddr, dest->sockaddrlen);274 sa = dest->sockaddr; 275 sa_len = dest->sockaddrlen; 267 276 } else { 268 struct sockaddr_un srv_addr;269 270 277 if (strlen(dest->addr)+1 > sizeof(srv_addr.sun_path)) { 271 278 return NT_STATUS_OBJECT_PATH_INVALID; 272 279 } 273 280 274 281 ZERO_STRUCT(srv_addr); 275 282 srv_addr.sun_family = AF_UNIX; 276 strncpy(srv_addr.sun_path, dest->addr, sizeof(srv_addr.sun_path)); 277 278 len = sendto(sock->fd, blob->data, blob->length, 0, 279 (struct sockaddr *)&srv_addr, sizeof(srv_addr)); 280 } 283 snprintf(srv_addr.sun_path, sizeof(srv_addr.sun_path), "%s", 284 dest->addr); 285 sa = (struct sockaddr *) &srv_addr; 286 sa_len = sizeof(srv_addr); 287 } 288 289 len = sendto(sock->fd, blob->data, blob->length, 0, sa, sa_len); 290 291 /* retry once */ 292 if (len == -1 && errno == EMSGSIZE) { 293 /* round up in 1K increments */ 294 int bufsize = ((blob->length + 1023) & (~1023)); 295 if (setsockopt(sock->fd, SOL_SOCKET, SO_SNDBUF, &bufsize, 296 sizeof(bufsize)) == -1) 297 { 298 return map_nt_error_from_unix_common(EMSGSIZE); 299 } 300 len = sendto(sock->fd, blob->data, blob->length, 0, sa, sa_len); 301 } 302 281 303 if (len == -1) { 282 return map_nt_error_from_unix (errno);304 return map_nt_error_from_unix_common(errno); 283 305 } 284 306 … … 302 324 static struct socket_address *unixdom_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) 303 325 { 304 struct sockaddr_ in *peer_addr;326 struct sockaddr_un *peer_addr; 305 327 socklen_t len = sizeof(*peer_addr); 306 328 struct socket_address *peer; … … 313 335 314 336 peer->family = sock->backend_name; 315 peer_addr = talloc(peer, struct sockaddr_ in);337 peer_addr = talloc(peer, struct sockaddr_un); 316 338 if (!peer_addr) { 317 339 talloc_free(peer); … … 341 363 static struct socket_address *unixdom_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) 342 364 { 343 struct sockaddr_ in *local_addr;365 struct sockaddr_un *local_addr; 344 366 socklen_t len = sizeof(*local_addr); 345 367 struct socket_address *local; … … 352 374 353 375 local->family = sock->backend_name; 354 local_addr = talloc(local, struct sockaddr_ in);376 local_addr = talloc(local, struct sockaddr_un); 355 377 if (!local_addr) { 356 378 talloc_free(local); … … 390 412 return NT_STATUS_OK; 391 413 } 392 return map_nt_error_from_unix (errno);414 return map_nt_error_from_unix_common(errno); 393 415 } 394 416 -
vendor/current/source4/lib/socket/testsuite.c
r740 r988 26 26 #include "lib/socket/netif.h" 27 27 #include "torture/torture.h" 28 #include "torture/local/proto.h" 28 29 #include "param/param.h" 29 30 #include "libcli/resolve/resolve.h" … … 43 44 struct interface *ifaces; 44 45 45 load_interface s(tctx, lpcfg_interfaces(tctx->lp_ctx), &ifaces);46 load_interface_list(tctx, tctx->lp_ctx, &ifaces); 46 47 47 48 status = socket_create("ip", SOCKET_TYPE_DGRAM, &sock1, 0); … … 54 55 55 56 localhost = socket_address_from_strings(sock1, sock1->backend_name, 56 iface_ best_ip(ifaces, "127.0.0.1"), 0);57 iface_list_best_ip(ifaces, "127.0.0.1"), 0); 57 58 58 59 torture_assert(tctx, localhost, "Localhost not found"); … … 63 64 srv_addr = socket_get_my_addr(sock1, mem_ctx); 64 65 torture_assert(tctx, srv_addr != NULL && 65 strcmp(srv_addr->addr, iface_ best_ip(ifaces, "127.0.0.1")) == 0,66 strcmp(srv_addr->addr, iface_list_best_ip(ifaces, "127.0.0.1")) == 0, 66 67 talloc_asprintf(tctx, 67 68 "Expected server address of %s but got %s", 68 iface_ best_ip(ifaces, "127.0.0.1"), srv_addr ? srv_addr->addr : NULL));69 iface_list_best_ip(ifaces, "127.0.0.1"), srv_addr ? srv_addr->addr : NULL)); 69 70 70 71 torture_comment(tctx, "server port is %d\n", srv_addr->port); … … 136 137 talloc_steal(mem_ctx, sock2); 137 138 138 load_interface s(tctx, lpcfg_interfaces(tctx->lp_ctx), &ifaces);139 load_interface_list(tctx, tctx->lp_ctx, &ifaces); 139 140 localhost = socket_address_from_strings(sock1, sock1->backend_name, 140 iface_ best_ip(ifaces, "127.0.0.1"), 0);141 iface_list_best_ip(ifaces, "127.0.0.1"), 0); 141 142 torture_assert(tctx, localhost, "Localhost not found"); 142 143 … … 148 149 "Unexpected socket_get_my_addr NULL\n"); 149 150 150 torture_assert_str_equal(tctx, srv_addr->addr, iface_ best_ip(ifaces, "127.0.0.1"),151 torture_assert_str_equal(tctx, srv_addr->addr, iface_list_best_ip(ifaces, "127.0.0.1"), 151 152 "Unexpected server address"); 152 153 -
vendor/current/source4/lib/socket/wscript_build
r740 r988 2 2 3 3 bld.SAMBA_LIBRARY('netif', 4 source='interface.c netif.c',5 autoproto='netif_proto.h',6 deps='samba-util',7 private_library=True8 )4 source='interface.c', 5 deps='samba-util interfaces samba-hostconfig', 6 private_library=True, 7 autoproto='netif_proto.h' 8 ) 9 9 10 10 bld.SAMBA_MODULE('socket_ip', 11 11 source='socket_ip.c', 12 12 subsystem='samba_socket', 13 deps=' errors',13 deps='samba-errors', 14 14 internal_module=True 15 15 ) … … 25 25 source='socket.c access.c connect_multi.c connect.c', 26 26 public_deps='talloc LIBTSOCKET', 27 deps=' LIBCLI_COMPOSITELIBCLI_RESOLVE socket_ip socket_unix'27 deps='cli_composite LIBCLI_RESOLVE socket_ip socket_unix' 28 28 ) 29 29
Note:
See TracChangeset
for help on using the changeset viewer.