Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

Location:
vendor/current/source4/lib/socket
Files:
1 deleted
11 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source4/lib/socket/access.c

    r740 r988  
    2828
    2929   The code has been considerably changed from the original. Bug reports
    30    should be sent to samba@samba.org
     30   should be sent to samba-technical@lists.samba.org
    3131*/
    3232
     
    250250
    251251/* return true if access should be allowed */
    252 bool allow_access(TALLOC_CTX *mem_ctx,
    253                   const char **deny_list, const char **allow_list,
    254                   const char *cname, const char *caddr)
     252bool socket_allow_access(TALLOC_CTX *mem_ctx,
     253                        const char **deny_list, const char **allow_list,
     254                        const char *cname, const char *caddr)
    255255{
    256256        bool ret;
     
    347347        }
    348348
    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);
    350350       
    351351        if (ret) {
  • vendor/current/source4/lib/socket/connect.c

    r414 r988  
    5959        }
    6060
    61         fde = event_add_fd(result->event_ctx, result,
     61        fde = tevent_add_fd(result->event_ctx, result,
    6262                           socket_get_fd(state->sock),
    63                            EVENT_FD_READ|EVENT_FD_WRITE,
     63                           TEVENT_FD_READ|TEVENT_FD_WRITE,
    6464                           socket_connect_handler, result);
    6565        composite_nomem(fde, result);
  • vendor/current/source4/lib/socket/connect_multi.c

    r740 r988  
    3434*/
    3535struct connect_multi_state {
    36         struct socket_address *server_address;
     36        struct socket_address **server_address;
     37        unsigned num_address, current_address, current_port;
    3738        int num_ports;
    3839        uint16_t *ports;
     
    4243
    4344        int num_connects_sent, num_connects_recv;
     45
     46        struct socket_connect_multi_ex *ex;
    4447};
    4548
     
    5962static void connect_multi_next_socket(struct composite_context *result);
    6063static void continue_one(struct composite_context *creq);
     64static 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*/
     127static 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*/
     191static 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*/
     203static 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*/
     226static 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*/
     274static 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
     327NTSTATUS 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}
    61344
    62345/*
     
    71354                                                    struct tevent_context *event_ctx)
    72355{
    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 */
    234363}
    235364
     
    242371                                   uint16_t *port)
    243372{
    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);
    254374}
    255375
     
    262382                              uint16_t *result_port)
    263383{
    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  
    2222#include "includes.h"
    2323#include "system/network.h"
     24#include "param/param.h"
    2425#include "lib/socket/netif.h"
    2526#include "../lib/util/util_net.h"
    2627#include "../lib/util/dlinklist.h"
    2728
    28 /** used for network interfaces */
     29/* used for network interfaces */
    2930struct interface {
    3031        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;
    3337        const char *ip_s;
    3438        const char *bcast_s;
     
    4650Try and find an interface that matches an ip. If we cannot, return NULL
    4751  **************************************************************************/
    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;
     52static 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        }
    5871
    5972        return NULL;
    6073}
    61 
    6274
    6375/****************************************************************************
    6476add an interface to the linked list of interfaces
    6577****************************************************************************/
    66 static void add_interface(TALLOC_CTX *mem_ctx, struct in_addr ip, struct in_addr nmask, struct interface **interfaces)
    67 {
     78static 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];
    6882        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) {
    7398                return;
    7499        }
     
    80105        ZERO_STRUCTPN(iface);
    81106
    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;
    85116
    86117        /* keep string versions too, to avoid people tripping over the implied
    87118           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}
    101140
    102141/**
     
    115154                                struct iface_struct *probed_ifaces,
    116155                                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;
    120164        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
    127169        /* first check if it is an interface name */
    128170        for (i=0;i<total_probed;i++) {
    129171                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        }
    137189
    138190        /* maybe it is a DNS name */
    139191        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));
    143196                        return;
    144197                }
    145                 ip.s_addr = interpret_addr2(token).s_addr;
     198
    146199                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);
    151203                                return;
    152204                        }
    153205                }
    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        }
    160211
    161212        /* 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        }
    165223
    166224        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                }
    168232        } 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)) {
    175256                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;
    180274                                return;
    181275                        }
    182276                }
    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);
    190296}
    191297
     
    194300load the list of network interfaces
    195301**/
    196 void load_interfaces(TALLOC_CTX *mem_ctx, const char **interfaces, struct interface **local_interfaces)
    197 {
    198         const char **ptr = interfaces;
     302void 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);
    199305        int i;
    200         struct iface_struct ifaces[MAX_INTERFACES];
    201         struct in_addr loopback_ip;
     306        struct iface_struct *ifaces = NULL;
    202307        int total_probed;
     308        bool enable_ipv6 = lpcfg_parm_bool(lp_ctx, NULL, "ipv6", "enable", true);
    203309
    204310        *local_interfaces = NULL;
    205311
    206         loopback_ip = interpret_addr2("127.0.0.1");
    207 
    208312        /* probe the kernel for interfaces */
    209         total_probed = get_interfaces(ifaces, MAX_INTERFACES);
     313        total_probed = get_interfaces(mem_ctx, &ifaces);
    210314
    211315        /* if we don't have a interfaces line then use all interfaces
     
    216320                }
    217321                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);
    221324                        }
    222325                }
     
    224327
    225328        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);
    227330                ptr++;
    228331        }
     
    231334                DEBUG(0,("WARNING: no network interfaces found\n"));
    232335        }
     336        talloc_free(ifaces);
    233337}
    234338
     
    236340  how many interfaces do we have
    237341  **/
    238 int iface_count(struct interface *ifaces)
     342int iface_list_count(struct interface *ifaces)
    239343{
    240344        int ret = 0;
     
    249353  return IP of the Nth interface
    250354  **/
    251 const char *iface_n_ip(struct interface *ifaces, int n)
     355const char *iface_list_n_ip(struct interface *ifaces, int n)
    252356{
    253357        struct interface *i;
     
    262366}
    263367
     368
     369/**
     370  return the first IPv4 interface address we have registered
     371  **/
     372const 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  **/
     387static 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  **/
     404bool 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
    264417/**
    265418  return bcast of the Nth interface
    266419  **/
    267 const char *iface_n_bcast(struct interface *ifaces, int n)
     420const char *iface_list_n_bcast(struct interface *ifaces, int n)
    268421{
    269422        struct interface *i;
     
    281434  return netmask of the Nth interface
    282435  **/
    283 const char *iface_n_netmask(struct interface *ifaces, int n)
     436const char *iface_list_n_netmask(struct interface *ifaces, int n)
    284437{
    285438        struct interface *i;
     
    298451  our first interface if none match
    299452*/
    300 const char *iface_best_ip(struct interface *ifaces, const char *dest)
     453const char *iface_list_best_ip(struct interface *ifaces, const char *dest)
    301454{
    302455        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);
    307462        if (iface) {
    308463                return iface->ip_s;
    309464        }
    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);
    311471}
    312472
     
    314474  return true if an IP is one one of our local networks
    315475*/
    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)) {
     476bool 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)) {
    322484                return true;
    323485        }
     
    328490  return true if a IP matches a IP/netmask pair
    329491*/
    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 }
     492bool 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*/
     515char **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  
    2121
    2222#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"
    3524#include "lib/socket/netif_proto.h"
    36 #endif
  • vendor/current/source4/lib/socket/socket.c

    r740 r988  
    353353        int ret;
    354354
     355        if (!a) {
     356                return NULL;
     357        }
    355358        if (a->sockaddr) {
    356359                ret = tsocket_address_bsd_from_sockaddr(mem_ctx,
     
    452455        fd = dup(sock->fd);
    453456        if (fd == -1) {
    454                 return map_nt_error_from_unix(errno);
     457                return map_nt_error_from_unix_common(errno);
    455458        }
    456459        close(sock->fd);
     
    474477        }
    475478
     479        if (strcmp(family, "ip") == 0 && is_ipaddress_v6(host)) {
     480                /* leaving as "ip" would force IPv4 */
     481                family = "ipv6";
     482        }
     483
    476484        addr->family = family;
    477485        addr->addr = talloc_strdup(addr, host);
     
    499507                return NULL;
    500508        }
    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        }
    502522        addr->addr = NULL;
    503523        addr->port = 0;
     
    508528        }
    509529        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
    510574        return addr;
    511575}
     
    568632}
    569633
    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_NODELAY
    583   {"TCP_NODELAY",       IPPROTO_TCP,   TCP_NODELAY,     0,                 OPT_BOOL},
    584 #endif
    585 #ifdef IPTOS_LOWDELAY
    586   {"IPTOS_LOWDELAY",    IPPROTO_IP,    IP_TOS,          IPTOS_LOWDELAY,    OPT_ON},
    587 #endif
    588 #ifdef IPTOS_THROUGHPUT
    589   {"IPTOS_THROUGHPUT",  IPPROTO_IP,    IP_TOS,          IPTOS_THROUGHPUT,  OPT_ON},
    590 #endif
    591 #ifdef SO_REUSEPORT
    592   {"SO_REUSEPORT",      SOL_SOCKET,    SO_REUSEPORT,    0,                 OPT_BOOL},
    593 #endif
    594 #ifdef SO_SNDBUF
    595   {"SO_SNDBUF",         SOL_SOCKET,    SO_SNDBUF,       0,                 OPT_INT},
    596 #endif
    597 #ifdef SO_RCVBUF
    598   {"SO_RCVBUF",         SOL_SOCKET,    SO_RCVBUF,       0,                 OPT_INT},
    599 #endif
    600 #ifdef SO_SNDLOWAT
    601   {"SO_SNDLOWAT",       SOL_SOCKET,    SO_SNDLOWAT,     0,                 OPT_INT},
    602 #endif
    603 #ifdef SO_RCVLOWAT
    604   {"SO_RCVLOWAT",       SOL_SOCKET,    SO_RCVLOWAT,     0,                 OPT_INT},
    605 #endif
    606 #ifdef SO_SNDTIMEO
    607   {"SO_SNDTIMEO",       SOL_SOCKET,    SO_SNDTIMEO,     0,                 OPT_INT},
    608 #endif
    609 #ifdef SO_RCVTIMEO
    610   {"SO_RCVTIMEO",       SOL_SOCKET,    SO_RCVTIMEO,     0,                 OPT_INT},
    611 #endif
    612   {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 
    674634/*
    675635  set some flags on a socket
  • vendor/current/source4/lib/socket/socket.h

    r740 r988  
    175175                                                    struct sockaddr *sockaddr,
    176176                                                    size_t addrlen);
     177struct sockaddr_storage;
     178struct socket_address *socket_address_from_sockaddr_storage(TALLOC_CTX *mem_ctx,
     179                                                            const struct sockaddr_storage *sockaddr,
     180                                                            uint16_t port);
    177181_PUBLIC_ void socket_address_set_port(struct socket_address *a,
    178182                                      uint16_t port);
     
    180184                                           const struct socket_address *oaddr);
    181185const struct socket_ops *socket_getops_byname(const char *name, enum socket_type type);
    182 bool allow_access(TALLOC_CTX *mem_ctx,
    183                   const char **deny_list, const char **allow_list,
    184                   const char *cname, const char *caddr);
     186bool socket_allow_access(TALLOC_CTX *mem_ctx,
     187                        const char **deny_list, const char **allow_list,
     188                        const char *cname, const char *caddr);
    185189bool socket_check_access(struct socket_context *sock,
    186190                         const char *service_name,
     
    198202                           uint32_t flags,
    199203                           struct tevent_context *ev);
     204
     205struct 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};
     214struct 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);
     221NTSTATUS socket_connect_multi_ex_recv(struct composite_context *ctx,
     222                                      TALLOC_CTX *mem_ctx,
     223                                      struct socket_context **result,
     224                                      uint16_t *port);
     225NTSTATUS 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);
    200232
    201233struct composite_context *socket_connect_multi_send(TALLOC_CTX *mem_ctx,
  • vendor/current/source4/lib/socket/socket_ip.c

    r740 r988  
    2828#include "lib/util/util_net.h"
    2929
     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
    3033static NTSTATUS ipv4_init(struct socket_context *sock)
    3134{
     
    4548        sock->fd = socket(PF_INET, type, 0);
    4649        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);
    4954
    5055        sock->backend_name = "ipv4";
     
    5661static void ip_close(struct socket_context *sock)
    5762{
    58         close(sock->fd);
     63        if (sock->fd != -1) {
     64                close(sock->fd);
     65                sock->fd = -1;
     66        }
    5967}
    6068
     
    6876        ret = getsockopt(sock->fd, SOL_SOCKET, SO_ERROR, &error, &len);
    6977        if (ret == -1) {
    70                 return map_nt_error_from_unix(errno);
     78                return map_nt_error_from_unix_common(errno);
    7179        }
    7280        if (error != 0) {
    73                 return map_nt_error_from_unix(error);
     81                return map_nt_error_from_unix_common(error);
    7482        }
    7583
     
    7785                ret = set_blocking(sock->fd, false);
    7886                if (ret == -1) {
    79                         return map_nt_error_from_unix(errno);
     87                        return map_nt_error_from_unix_common(errno);
    8088                }
    8189        }
     
    100108                ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen);
    101109                if (ret == -1) {
    102                         return map_nt_error_from_unix(errno);
     110                        return map_nt_error_from_unix_common(errno);
    103111                }
    104112        } else if (my_address) {
     
    117125                        ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
    118126                        if (ret == -1) {
    119                                 return map_nt_error_from_unix(errno);
     127                                return map_nt_error_from_unix_common(errno);
    120128                        }
    121129                }
     
    125133                ret = connect(sock->fd, srv_address->sockaddr, srv_address->sockaddrlen);
    126134                if (ret == -1) {
    127                         return map_nt_error_from_unix(errno);
     135                        return map_nt_error_from_unix_common(errno);
    128136                }
    129137        } else {
     
    145153                ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr));
    146154                if (ret == -1) {
    147                         return map_nt_error_from_unix(errno);
     155                        return map_nt_error_from_unix_common(errno);
    148156                }
    149157        }
     
    184192
    185193        if (ret == -1) {
    186                 return map_nt_error_from_unix(errno);
     194                return map_nt_error_from_unix_common(errno);
    187195        }
    188196
     
    190198                ret = listen(sock->fd, queue_size);
    191199                if (ret == -1) {
    192                         return map_nt_error_from_unix(errno);
     200                        return map_nt_error_from_unix_common(errno);
    193201                }
    194202        }
     
    197205                ret = set_blocking(sock->fd, false);
    198206                if (ret == -1) {
    199                         return map_nt_error_from_unix(errno);
     207                        return map_nt_error_from_unix_common(errno);
    200208                }
    201209        }
     
    218226        new_fd = accept(sock->fd, (struct sockaddr *)&cli_addr, &cli_addr_len);
    219227        if (new_fd == -1) {
    220                 return map_nt_error_from_unix(errno);
     228                return map_nt_error_from_unix_common(errno);
    221229        }
    222230
     
    225233                if (ret == -1) {
    226234                        close(new_fd);
    227                         return map_nt_error_from_unix(errno);
     235                        return map_nt_error_from_unix_common(errno);
    228236                }
    229237        }
     
    266274                return NT_STATUS_END_OF_FILE;
    267275        } else if (gotlen == -1) {
    268                 return map_nt_error_from_unix(errno);
     276                return map_nt_error_from_unix_common(errno);
    269277        }
    270278
     
    309317        } else if (gotlen == -1) {
    310318                talloc_free(src);
    311                 return map_nt_error_from_unix(errno);
     319                return map_nt_error_from_unix_common(errno);
    312320        }
    313321
     
    340348        len = send(sock->fd, blob->data, blob->length, 0);
    341349        if (len == -1) {
    342                 return map_nt_error_from_unix(errno);
     350                return map_nt_error_from_unix_common(errno);
    343351        }       
    344352
     
    381389        }
    382390        if (len == -1) {
    383                 return map_nt_error_from_unix(errno);
     391                return map_nt_error_from_unix_common(errno);
    384392        }       
    385393
     
    516524                return NT_STATUS_OK;
    517525        }
    518         return map_nt_error_from_unix(errno);
     526        return map_nt_error_from_unix_common(errno);
    519527}
    520528
     
    602610        sock->fd = socket(PF_INET6, type, 0);
    603611        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);
    606616
    607617        sock->backend_name = "ipv6";
     
    621631                ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen);
    622632                if (ret == -1) {
    623                         return map_nt_error_from_unix(errno);
     633                        return map_nt_error_from_unix_common(errno);
    624634                }
    625635        } else if (my_address) {
     
    636646                        ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
    637647                        if (ret == -1) {
    638                                 return map_nt_error_from_unix(errno);
     648                                return map_nt_error_from_unix_common(errno);
    639649                        }
    640650                }
     
    659669        }
    660670        if (ret == -1) {
    661                 return map_nt_error_from_unix(errno);
     671                return map_nt_error_from_unix_common(errno);
    662672        }
    663673
     
    665675}
    666676
     677/*
     678  fix the sin6_scope_id based on the address interface
     679 */
     680static 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
    667690static NTSTATUS ipv6_listen(struct socket_context *sock,
    668                                 const struct socket_address *my_address,
    669                                 int queue_size, uint32_t flags)
     691                            const struct socket_address *my_address,
     692                            int queue_size, uint32_t flags)
    670693{
    671694        struct sockaddr_in6 my_addr;
     
    678701                ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen);
    679702        } else {
     703                int one = 1;
    680704                ip_addr = interpret_addr6(my_address->addr);
    681705               
     
    684708                my_addr.sin6_port       = htons(my_address->port);
    685709                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                }
    688718        }
    689719
    690720        if (ret == -1) {
    691                 return map_nt_error_from_unix(errno);
     721                return map_nt_error_from_unix_common(errno);
    692722        }
    693723
     
    695725                ret = listen(sock->fd, queue_size);
    696726                if (ret == -1) {
    697                         return map_nt_error_from_unix(errno);
     727                        return map_nt_error_from_unix_common(errno);
    698728                }
    699729        }
     
    702732                ret = set_blocking(sock->fd, false);
    703733                if (ret == -1) {
    704                         return map_nt_error_from_unix(errno);
     734                        return map_nt_error_from_unix_common(errno);
    705735                }
    706736        }
     
    723753        new_fd = accept(sock->fd, (struct sockaddr *)&cli_addr, &cli_addr_len);
    724754        if (new_fd == -1) {
    725                 return map_nt_error_from_unix(errno);
     755                return map_nt_error_from_unix_common(errno);
    726756        }
    727757
     
    730760                if (ret == -1) {
    731761                        close(new_fd);
    732                         return map_nt_error_from_unix(errno);
     762                        return map_nt_error_from_unix_common(errno);
    733763                }
    734764        }
     
    794824        } else if (gotlen == -1) {
    795825                talloc_free(src);
    796                 return map_nt_error_from_unix(errno);
     826                return map_nt_error_from_unix_common(errno);
    797827        }
    798828
     
    845875        }
    846876        if (len == -1) {
    847                 return map_nt_error_from_unix(errno);
     877                return map_nt_error_from_unix_common(errno);
    848878        }       
    849879
  • vendor/current/source4/lib/socket/socket_unix.c

    r414 r988  
    2626#include "system/filesys.h"
    2727
     28_PUBLIC_ const struct socket_ops *socket_unixdom_ops(enum socket_type type);
    2829
    2930
     
    3334static NTSTATUS unixdom_error(int ernum)
    3435{
    35         return map_nt_error_from_unix(ernum);
     36        return map_nt_error_from_unix_common(ernum);
    3637}
    3738
     
    5354        sock->fd = socket(PF_UNIX, type, 0);
    5455        if (sock->fd == -1) {
    55                 return map_nt_error_from_unix(errno);
     56                return map_nt_error_from_unix_common(errno);
    5657        }
    5758        sock->private_data = NULL;
    5859
    5960        sock->backend_name = "unix";
     61
     62        smb_set_close_on_exec(sock->fd);
    6063
    6164        return NT_STATUS_OK;
     
    7679        ret = getsockopt(sock->fd, SOL_SOCKET, SO_ERROR, &error, &len);
    7780        if (ret == -1) {
    78                 return map_nt_error_from_unix(errno);
     81                return map_nt_error_from_unix_common(errno);
    7982        }
    8083        if (error != 0) {
    81                 return map_nt_error_from_unix(error);
     84                return map_nt_error_from_unix_common(error);
    8285        }
    8386
     
    8588                ret = set_blocking(sock->fd, false);
    8689                if (ret == -1) {
    87                         return map_nt_error_from_unix(errno);
     90                        return map_nt_error_from_unix_common(errno);
    8891                }
    8992        }
     
    111114                ZERO_STRUCT(srv_addr);
    112115                srv_addr.sun_family = AF_UNIX;
    113                 strncpy(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);
    114117
    115118                ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr));
     
    146149                ZERO_STRUCT(my_addr);
    147150                my_addr.sun_family = AF_UNIX;
    148                 strncpy(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
    150153                ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
    151154        }
     
    194197                if (ret == -1) {
    195198                        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);
    199204
    200205        (*new_sock) = talloc(NULL, struct socket_context);
     
    259264                               const struct socket_address *dest)
    260265{
     266        struct sockaddr_un srv_addr;
     267        const struct sockaddr *sa;
     268        socklen_t sa_len;
    261269        ssize_t len;
     270
    262271        *sendlen = 0;
    263                
     272
    264273        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;
    267276        } else {
    268                 struct sockaddr_un srv_addr;
    269                
    270277                if (strlen(dest->addr)+1 > sizeof(srv_addr.sun_path)) {
    271278                        return NT_STATUS_OBJECT_PATH_INVALID;
    272279                }
    273                
     280
    274281                ZERO_STRUCT(srv_addr);
    275282                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
    281303        if (len == -1) {
    282                 return map_nt_error_from_unix(errno);
     304                return map_nt_error_from_unix_common(errno);
    283305        }       
    284306
     
    302324static struct socket_address *unixdom_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
    303325{
    304         struct sockaddr_in *peer_addr;
     326        struct sockaddr_un *peer_addr;
    305327        socklen_t len = sizeof(*peer_addr);
    306328        struct socket_address *peer;
     
    313335       
    314336        peer->family = sock->backend_name;
    315         peer_addr = talloc(peer, struct sockaddr_in);
     337        peer_addr = talloc(peer, struct sockaddr_un);
    316338        if (!peer_addr) {
    317339                talloc_free(peer);
     
    341363static struct socket_address *unixdom_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
    342364{
    343         struct sockaddr_in *local_addr;
     365        struct sockaddr_un *local_addr;
    344366        socklen_t len = sizeof(*local_addr);
    345367        struct socket_address *local;
     
    352374       
    353375        local->family = sock->backend_name;
    354         local_addr = talloc(local, struct sockaddr_in);
     376        local_addr = talloc(local, struct sockaddr_un);
    355377        if (!local_addr) {
    356378                talloc_free(local);
     
    390412                return NT_STATUS_OK;
    391413        }
    392         return map_nt_error_from_unix(errno);
     414        return map_nt_error_from_unix_common(errno);
    393415}
    394416
  • vendor/current/source4/lib/socket/testsuite.c

    r740 r988  
    2626#include "lib/socket/netif.h"
    2727#include "torture/torture.h"
     28#include "torture/local/proto.h"
    2829#include "param/param.h"
    2930#include "libcli/resolve/resolve.h"
     
    4344        struct interface *ifaces;
    4445
    45         load_interfaces(tctx, lpcfg_interfaces(tctx->lp_ctx), &ifaces);
     46        load_interface_list(tctx, tctx->lp_ctx, &ifaces);
    4647
    4748        status = socket_create("ip", SOCKET_TYPE_DGRAM, &sock1, 0);
     
    5455
    5556        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);
    5758
    5859        torture_assert(tctx, localhost, "Localhost not found");
     
    6364        srv_addr = socket_get_my_addr(sock1, mem_ctx);
    6465        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,
    6667                                   talloc_asprintf(tctx,
    6768                "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));
    6970
    7071        torture_comment(tctx, "server port is %d\n", srv_addr->port);
     
    136137        talloc_steal(mem_ctx, sock2);
    137138
    138         load_interfaces(tctx, lpcfg_interfaces(tctx->lp_ctx), &ifaces);
     139        load_interface_list(tctx, tctx->lp_ctx, &ifaces);
    139140        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);
    141142        torture_assert(tctx, localhost, "Localhost not found");
    142143
     
    148149                                   "Unexpected socket_get_my_addr NULL\n");
    149150
    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"),
    151152                        "Unexpected server address");
    152153
  • vendor/current/source4/lib/socket/wscript_build

    r740 r988  
    22
    33bld.SAMBA_LIBRARY('netif',
    4     source='interface.c netif.c',
    5     autoproto='netif_proto.h',
    6     deps='samba-util',
    7     private_library=True
    8     )
     4                  source='interface.c',
     5                  deps='samba-util interfaces samba-hostconfig',
     6                  private_library=True,
     7                  autoproto='netif_proto.h'
     8                  )
    99
    1010bld.SAMBA_MODULE('socket_ip',
    1111    source='socket_ip.c',
    1212    subsystem='samba_socket',
    13     deps='errors',
     13    deps='samba-errors',
    1414    internal_module=True
    1515    )
     
    2525    source='socket.c access.c connect_multi.c connect.c',
    2626    public_deps='talloc LIBTSOCKET',
    27     deps='LIBCLI_COMPOSITE LIBCLI_RESOLVE socket_ip socket_unix'
     27    deps='cli_composite LIBCLI_RESOLVE socket_ip socket_unix'
    2828    )
    2929
Note: See TracChangeset for help on using the changeset viewer.