Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source3/lib/util_sock.c

    r599 r745  
    2121
    2222#include "includes.h"
    23 
    24 /****************************************************************************
    25  Get a port number in host byte order from a sockaddr_storage.
    26 ****************************************************************************/
    27 
    28 uint16_t get_sockaddr_port(const struct sockaddr_storage *pss)
    29 {
    30         uint16_t port = 0;
    31 
    32         if (pss->ss_family != AF_INET) {
    33 #if defined(HAVE_IPV6)
    34                 /* IPv6 */
    35                 const struct sockaddr_in6 *sa6 =
    36                         (const struct sockaddr_in6 *)pss;
    37                 port = ntohs(sa6->sin6_port);
    38 #endif
    39         } else {
    40                 const struct sockaddr_in *sa =
    41                         (const struct sockaddr_in *)pss;
    42                 port = ntohs(sa->sin_port);
    43         }
    44         return port;
    45 }
    46 
    47 /****************************************************************************
    48  Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
    49 ****************************************************************************/
    50 
    51 static char *print_sockaddr_len(char *dest,
    52                         size_t destlen,
    53                         const struct sockaddr *psa,
    54                         socklen_t psalen)
    55 {
    56         if (destlen > 0) {
    57                 dest[0] = '\0';
    58         }
    59         (void)sys_getnameinfo(psa,
    60                         psalen,
    61                         dest, destlen,
    62                         NULL, 0,
    63                         NI_NUMERICHOST);
    64         return dest;
    65 }
    66 
    67 /****************************************************************************
    68  Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
    69 ****************************************************************************/
    70 
    71 char *print_sockaddr(char *dest,
    72                         size_t destlen,
    73                         const struct sockaddr_storage *psa)
    74 {
    75         return print_sockaddr_len(dest, destlen, (struct sockaddr *)psa,
    76                         sizeof(struct sockaddr_storage));
    77 }
    78 
    79 /****************************************************************************
    80  Print out a canonical IPv4 or IPv6 address from a struct sockaddr_storage.
    81 ****************************************************************************/
    82 
    83 char *print_canonical_sockaddr(TALLOC_CTX *ctx,
    84                         const struct sockaddr_storage *pss)
    85 {
    86         char addr[INET6_ADDRSTRLEN];
    87         char *dest = NULL;
    88         int ret;
    89 
    90         /* Linux getnameinfo() man pages says port is unitialized if
    91            service name is NULL. */
    92 
    93         ret = sys_getnameinfo((const struct sockaddr *)pss,
    94                         sizeof(struct sockaddr_storage),
    95                         addr, sizeof(addr),
    96                         NULL, 0,
    97                         NI_NUMERICHOST);
    98         if (ret != 0) {
    99                 return NULL;
    100         }
    101 
    102         if (pss->ss_family != AF_INET) {
    103 #if defined(HAVE_IPV6)
    104                 dest = talloc_asprintf(ctx, "[%s]", addr);
    105 #else
    106                 return NULL;
    107 #endif
    108         } else {
    109                 dest = talloc_asprintf(ctx, "%s", addr);
    110         }
    111        
    112         return dest;
    113 }
    114 
    115 /****************************************************************************
    116  Return the string of an IP address (IPv4 or IPv6).
    117 ****************************************************************************/
    118 
    119 static const char *get_socket_addr(int fd, char *addr_buf, size_t addr_len)
    120 {
    121         struct sockaddr_storage sa;
    122         socklen_t length = sizeof(sa);
    123 
    124         /* Ok, returning a hard coded IPv4 address
    125          * is bogus, but it's just as bogus as a
    126          * zero IPv6 address. No good choice here.
    127          */
    128 
    129         strlcpy(addr_buf, "0.0.0.0", addr_len);
    130 
    131         if (fd == -1) {
    132                 return addr_buf;
    133         }
    134 
    135         if (getsockname(fd, (struct sockaddr *)&sa, &length) < 0) {
    136                 DEBUG(0,("getsockname failed. Error was %s\n",
    137                         strerror(errno) ));
    138                 return addr_buf;
    139         }
    140 
    141         return print_sockaddr_len(addr_buf, addr_len, (struct sockaddr *)&sa, length);
    142 }
    143 
    144 /****************************************************************************
    145  Return the port number we've bound to on a socket.
    146 ****************************************************************************/
    147 
    148 int get_socket_port(int fd)
    149 {
    150         struct sockaddr_storage sa;
    151         socklen_t length = sizeof(sa);
    152 
    153         if (fd == -1) {
    154                 return -1;
    155         }
    156 
    157         if (getsockname(fd, (struct sockaddr *)&sa, &length) < 0) {
    158                 DEBUG(0,("getpeername failed. Error was %s\n",
    159                         strerror(errno) ));
    160                 return -1;
    161         }
    162 
    163 #if defined(HAVE_IPV6)
    164         if (sa.ss_family == AF_INET6) {
    165                 return ntohs(((struct sockaddr_in6 *)&sa)->sin6_port);
    166         }
    167 #endif
    168         if (sa.ss_family == AF_INET) {
    169                 return ntohs(((struct sockaddr_in *)&sa)->sin_port);
    170         }
    171         return -1;
    172 }
     23#include "system/filesys.h"
     24#include "memcache.h"
     25#include "../lib/async_req/async_sock.h"
     26#include "../lib/util/select.h"
     27#include "interfaces.h"
     28#include "../lib/util/tevent_unix.h"
     29#include "../lib/util/tevent_ntstatus.h"
    17330
    17431const char *client_name(int fd)
     
    18037{
    18138        return get_peer_addr(fd,addr,addrlen);
    182 }
    183 
    184 const char *client_socket_addr(int fd, char *addr, size_t addr_len)
    185 {
    186         return get_socket_addr(fd, addr, addr_len);
    18739}
    18840
     
    285137#ifdef TCP_QUICKACK
    286138  {"TCP_QUICKACK", IPPROTO_TCP, TCP_QUICKACK, 0, OPT_BOOL},
     139#endif
     140#ifdef TCP_KEEPALIVE_THRESHOLD
     141  {"TCP_KEEPALIVE_THRESHOLD", IPPROTO_TCP, TCP_KEEPALIVE_THRESHOLD, 0, OPT_INT},
     142#endif
     143#ifdef TCP_KEEPALIVE_ABORT_THRESHOLD
     144  {"TCP_KEEPALIVE_ABORT_THRESHOLD", IPPROTO_TCP, TCP_KEEPALIVE_ABORT_THRESHOLD, 0, OPT_INT},
    287145#endif
    288146  {NULL,0,0,0,0}};
     
    437295                                  size_t *size_ret)
    438296{
    439         fd_set fds;
    440         int selrtn;
     297        int pollrtn;
    441298        ssize_t readret;
    442299        size_t nread = 0;
    443         struct timeval timeout;
    444         char addr[INET6_ADDRSTRLEN];
    445         int save_errno;
    446300
    447301        /* just checking .... */
     
    465319
    466320                        if (readret == -1) {
    467                                 save_errno = errno;
    468                                 if (fd == get_client_fd()) {
    469                                         /* Try and give an error message
    470                                          * saying what client failed. */
    471                                         DEBUG(0,("read_fd_with_timeout: "
    472                                                 "client %s read error = %s.\n",
    473                                                 get_peer_addr(fd,addr,sizeof(addr)),
    474                                                 strerror(save_errno) ));
    475                                 } else {
    476                                         DEBUG(0,("read_fd_with_timeout: "
    477                                                 "read error = %s.\n",
    478                                                 strerror(save_errno) ));
    479                                 }
    480                                 return map_nt_error_from_unix(save_errno);
     321                                return map_nt_error_from_unix(errno);
    481322                        }
    482323                        nread += readret;
     
    491332           select always returns true on disk files */
    492333
    493         /* Set initial timeout */
    494         timeout.tv_sec = (time_t)(time_out / 1000);
    495         timeout.tv_usec = (long)(1000 * (time_out % 1000));
    496 
    497334        for (nread=0; nread < mincnt; ) {
    498                 if (fd < 0 || fd >= FD_SETSIZE) {
    499                         errno = EBADF;
    500                         return map_nt_error_from_unix(EBADF);
    501                 }
    502 
    503                 FD_ZERO(&fds);
    504                 FD_SET(fd,&fds);
    505 
    506                 selrtn = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout);
     335                int revents;
     336
     337                pollrtn = poll_intr_one_fd(fd, POLLIN|POLLHUP, time_out,
     338                                           &revents);
    507339
    508340                /* Check if error */
    509                 if (selrtn == -1) {
    510                         save_errno = errno;
    511                         /* something is wrong. Maybe the socket is dead? */
    512                         if (fd == get_client_fd()) {
    513                                 /* Try and give an error message saying
    514                                  * what client failed. */
    515                                 DEBUG(0,("read_fd_with_timeout: timeout "
    516                                 "read for client %s. select error = %s.\n",
    517                                 get_peer_addr(fd,addr,sizeof(addr)),
    518                                 strerror(save_errno) ));
    519                         } else {
    520                                 DEBUG(0,("read_fd_with_timeout: timeout "
    521                                 "read. select error = %s.\n",
    522                                 strerror(save_errno) ));
    523                         }
    524                         return map_nt_error_from_unix(save_errno);
     341                if (pollrtn == -1) {
     342                        return map_nt_error_from_unix(errno);
    525343                }
    526344
    527345                /* Did we timeout ? */
    528                 if (selrtn == 0) {
     346                if ((pollrtn == 0) ||
     347                    ((revents & (POLLIN|POLLHUP|POLLERR)) == 0)) {
    529348                        DEBUG(10,("read_fd_with_timeout: timeout read. "
    530349                                "select timed out.\n"));
     
    542361
    543362                if (readret == -1) {
    544                         save_errno = errno;
    545                         /* the descriptor is probably dead */
    546                         if (fd == get_client_fd()) {
    547                                 /* Try and give an error message
    548                                  * saying what client failed. */
    549                                 DEBUG(0,("read_fd_with_timeout: timeout "
    550                                         "read to client %s. read error = %s.\n",
    551                                         get_peer_addr(fd,addr,sizeof(addr)),
    552                                         strerror(save_errno) ));
    553                         } else {
    554                                 DEBUG(0,("read_fd_with_timeout: timeout "
    555                                         "read. read error = %s.\n",
    556                                         strerror(save_errno) ));
    557                         }
    558363                        return map_nt_error_from_unix(errno);
    559364                }
     
    660465ssize_t write_data(int fd, const char *buffer, size_t N)
    661466{
    662         ssize_t ret;
    663467        struct iovec iov;
    664468
    665469        iov.iov_base = CONST_DISCARD(void *, buffer);
    666470        iov.iov_len = N;
    667 
    668         ret = write_data_iov(fd, &iov, 1);
    669         if (ret >= 0) {
    670                 return ret;
    671         }
    672 
    673         if (fd == get_client_fd()) {
    674                 char addr[INET6_ADDRSTRLEN];
    675                 /*
    676                  * Try and give an error message saying what client failed.
    677                  */
    678                 DEBUG(0, ("write_data: write failure in writing to client %s. "
    679                           "Error %s\n", get_peer_addr(fd,addr,sizeof(addr)),
    680                           strerror(errno)));
    681         } else {
    682                 DEBUG(0,("write_data: write failure. Error = %s\n",
    683                          strerror(errno) ));
    684         }
    685 
    686         return -1;
     471        return write_data_iov(fd, &iov, 1);
    687472}
    688473
     
    730515
    731516        DEBUG(10,("got smb length of %lu\n",(unsigned long)(*len)));
    732 
    733         return NT_STATUS_OK;
    734 }
    735 
    736 /****************************************************************************
    737  Read 4 bytes of a smb packet and return the smb length of the packet.
    738  Store the result in the buffer. This version of the function will
    739  never return a session keepalive (length of zero).
    740  Timeout is in milliseconds.
    741 ****************************************************************************/
    742 
    743 NTSTATUS read_smb_length(int fd, char *inbuf, unsigned int timeout,
    744                          size_t *len)
    745 {
    746         uint8_t msgtype = SMBkeepalive;
    747 
    748         while (msgtype == SMBkeepalive) {
    749                 NTSTATUS status;
    750 
    751                 status = read_smb_length_return_keepalive(fd, inbuf, timeout,
    752                                                           len);
    753                 if (!NT_STATUS_IS_OK(status)) {
    754                         return status;
    755                 }
    756 
    757                 msgtype = CVAL(inbuf, 0);
    758         }
    759 
    760         DEBUG(10,("read_smb_length: got smb length of %lu\n",
    761                   (unsigned long)len));
    762517
    763518        return NT_STATUS_OK;
     
    782537
    783538        if (!NT_STATUS_IS_OK(status)) {
    784                 DEBUG(10, ("receive_smb_raw: %s!\n", nt_errstr(status)));
     539                DEBUG(0, ("read_fd_with_timeout failed, read "
     540                          "error = %s.\n", nt_errstr(status)));
    785541                return status;
    786542        }
     
    801557
    802558                if (!NT_STATUS_IS_OK(status)) {
     559                        DEBUG(0, ("read_fd_with_timeout failed, read error = "
     560                                  "%s.\n", nt_errstr(status)));
    803561                        return status;
    804562                }
     
    876634        }
    877635
     636#ifdef HAVE_IPV6
     637        /*
     638         * As IPV6_V6ONLY is the default on some systems,
     639         * we better try to be consistent and always use it.
     640         *
     641         * This also avoids using IPv4 via AF_INET6 sockets
     642         * and makes sure %I never resolves to a '::ffff:192.168.0.1'
     643         * string.
     644         */
     645        if (sock.ss_family == AF_INET6) {
     646                int val = 1;
     647                int ret;
     648
     649                ret = setsockopt(res, IPPROTO_IPV6, IPV6_V6ONLY,
     650                                 (const void *)&val, sizeof(val));
     651                if (ret == -1) {
     652                        if(DEBUGLVL(0)) {
     653                                dbgtext("open_socket_in(): IPV6_ONLY failed: ");
     654                                dbgtext("%s\n", strerror(errno));
     655                        }
     656                        close(res);
     657                        return -1;
     658                }
     659        }
     660#endif
     661
    878662        /* now we've got a socket - we need to bind it */
    879663        if (bind(res, (struct sockaddr *)&sock, slen) == -1 ) {
     
    1072856}
    1073857
     858/**
     859* @brief open a socket
     860*
     861* @param pss a struct sockaddr_storage defining the address to connect to
     862* @param port to connect to
     863* @param timeout in MILLISECONDS
     864* @param pfd file descriptor returned
     865*
     866* @return NTSTATUS code
     867*/
    1074868NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port,
    1075869                         int timeout, int *pfd)
     
    1197991}
    1198992
    1199 /*******************************************************************
    1200  Create an outgoing TCP socket to the first addr that connects.
    1201 
    1202  This is for simultaneous connection attempts to port 445 and 139 of a host
    1203  or for simultatneous connection attempts to multiple DCs at once.  We return
    1204  a socket fd of the first successful connection.
    1205 
    1206  @param[in] addrs list of Internet addresses and ports to connect to
    1207  @param[in] num_addrs number of address/port pairs in the addrs list
    1208  @param[in] timeout time after which we stop waiting for a socket connection
    1209             to succeed, given in milliseconds
    1210  @param[out] fd_index the entry in addrs which we successfully connected to
    1211  @param[out] fd fd of the open and connected socket
    1212  @return true on a successful connection, false if all connection attempts
    1213          failed or we timed out
    1214 *******************************************************************/
    1215 
    1216 bool open_any_socket_out(struct sockaddr_storage *addrs, int num_addrs,
    1217                          int timeout, int *fd_index, int *fd)
    1218 {
    1219         int i, resulting_index, res;
    1220         int *sockets;
    1221         bool good_connect;
    1222 
    1223         fd_set r_fds, wr_fds;
    1224         struct timeval tv;
    1225         int maxfd;
    1226 
    1227         int connect_loop = 10000; /* 10 milliseconds */
    1228 
    1229         timeout *= 1000;        /* convert to microseconds */
    1230 
    1231         sockets = SMB_MALLOC_ARRAY(int, num_addrs);
    1232 
    1233         if (sockets == NULL)
    1234                 return false;
    1235 
    1236         resulting_index = -1;
    1237 
    1238         for (i=0; i<num_addrs; i++)
    1239                 sockets[i] = -1;
    1240 
    1241         for (i=0; i<num_addrs; i++) {
    1242                 sockets[i] = socket(addrs[i].ss_family, SOCK_STREAM, 0);
    1243                 if (sockets[i] < 0 || sockets[i] >= FD_SETSIZE)
    1244                         goto done;
    1245                 set_blocking(sockets[i], false);
    1246         }
    1247 
    1248  connect_again:
    1249         good_connect = false;
    1250 
    1251         for (i=0; i<num_addrs; i++) {
    1252                 const struct sockaddr * a =
    1253                     (const struct sockaddr *)&(addrs[i]);
    1254 
    1255                 if (sockets[i] == -1)
    1256                         continue;
    1257 
    1258                 if (sys_connect(sockets[i], a) == 0) {
    1259                         /* Rather unlikely as we are non-blocking, but it
    1260                          * might actually happen. */
    1261                         resulting_index = i;
    1262                         goto done;
    1263                 }
    1264 
    1265                 if (errno == EINPROGRESS || errno == EALREADY ||
    1266 #ifdef EISCONN
    1267                         errno == EISCONN ||
    1268 #endif
    1269                     errno == EAGAIN || errno == EINTR) {
    1270                         /* These are the error messages that something is
    1271                            progressing. */
    1272                         good_connect = true;
    1273                 } else if (errno != 0) {
    1274                         /* There was a direct error */
    1275                         close(sockets[i]);
    1276                         sockets[i] = -1;
    1277                 }
    1278         }
    1279 
    1280         if (!good_connect) {
    1281                 /* All of the connect's resulted in real error conditions */
    1282                 goto done;
    1283         }
    1284 
    1285         /* Lets see if any of the connect attempts succeeded */
    1286 
    1287         maxfd = 0;
    1288         FD_ZERO(&wr_fds);
    1289         FD_ZERO(&r_fds);
    1290 
    1291         for (i=0; i<num_addrs; i++) {
    1292                 if (sockets[i] < 0 || sockets[i] >= FD_SETSIZE) {
    1293                         /* This cannot happen - ignore if so. */
    1294                         continue;
    1295                 }
    1296                 FD_SET(sockets[i], &wr_fds);
    1297                 FD_SET(sockets[i], &r_fds);
    1298                 if (sockets[i]>maxfd)
    1299                         maxfd = sockets[i];
    1300         }
    1301 
    1302         tv.tv_sec = 0;
    1303         tv.tv_usec = connect_loop;
    1304 
    1305         res = sys_select_intr(maxfd+1, &r_fds, &wr_fds, NULL, &tv);
    1306 
    1307         if (res < 0)
    1308                 goto done;
    1309 
    1310         if (res == 0)
    1311                 goto next_round;
    1312 
    1313         for (i=0; i<num_addrs; i++) {
    1314 
    1315                 if (sockets[i] < 0 || sockets[i] >= FD_SETSIZE) {
    1316                         /* This cannot happen - ignore if so. */
    1317                         continue;
    1318                 }
    1319 
    1320                 /* Stevens, Network Programming says that if there's a
    1321                  * successful connect, the socket is only writable. Upon an
    1322                  * error, it's both readable and writable. */
    1323 
    1324                 if (FD_ISSET(sockets[i], &r_fds) &&
    1325                     FD_ISSET(sockets[i], &wr_fds)) {
    1326                         /* readable and writable, so it's an error */
    1327                         close(sockets[i]);
    1328                         sockets[i] = -1;
    1329                         continue;
    1330                 }
    1331 
    1332                 if (!FD_ISSET(sockets[i], &r_fds) &&
    1333                     FD_ISSET(sockets[i], &wr_fds)) {
    1334                         /* Only writable, so it's connected */
    1335                         resulting_index = i;
    1336                         goto done;
    1337                 }
    1338         }
    1339 
    1340  next_round:
    1341 
    1342         timeout -= connect_loop;
    1343         if (timeout <= 0)
    1344                 goto done;
    1345         connect_loop *= 1.5;
    1346         if (connect_loop > timeout)
    1347                 connect_loop = timeout;
    1348         goto connect_again;
    1349 
    1350  done:
    1351         for (i=0; i<num_addrs; i++) {
    1352                 if (i == resulting_index)
    1353                         continue;
    1354                 if (sockets[i] >= 0)
    1355                         close(sockets[i]);
    1356         }
    1357 
    1358         if (resulting_index >= 0) {
    1359                 *fd_index = resulting_index;
    1360                 *fd = sockets[*fd_index];
    1361                 set_blocking(*fd, true);
    1362         }
    1363 
    1364         free(sockets);
    1365 
    1366         return (resulting_index >= 0);
    1367 }
    1368993/****************************************************************************
    1369994 Open a connected UDP socket to host on port
     
    14381063
    14391064        if (getpeername(fd, (struct sockaddr *)pss, plength) < 0) {
    1440                 DEBUG(0,("getpeername failed. Error was %s\n",
    1441                                         strerror(errno) ));
     1065                int level = (errno == ENOTCONN) ? 2 : 0;
     1066                DEBUG(level, ("getpeername failed. Error was %s\n",
     1067                               strerror(errno)));
    14421068                return addr_buf;
    14431069        }
     
    17311357#ifdef __OS2__
    17321358        if (asprintf(&path, "\\socket\\samba\\%s\\%s", socket_dir, socket_name) == -1) {
    1733 #else       
     1359#else
    17341360        if (asprintf(&path, "%s/%s", socket_dir, socket_name) == -1) {
    17351361#endif
     
    18631489        }
    18641490
    1865         if (is_zero_addr((struct sockaddr *)&ss) ||
     1491        if (is_zero_addr(&ss) ||
    18661492                is_loopback_addr((struct sockaddr *)&ss)) {
    18671493                return false;
     
    19331559        }
    19341560
     1561        /* Maybe its an IP address? */
     1562        if (is_ipaddress(servername)) {
     1563                return is_my_ipaddr(servername);
     1564        }
     1565
    19351566        /* Handle possible CNAME records - convert to an IP addr. list. */
    1936         if (!is_ipaddress(servername)) {
     1567        {
    19371568                /* Use DNS to resolve the name, check all addresses. */
    19381569                struct addrinfo *p = NULL;
     
    19621593        }
    19631594
    1964         /* Maybe its an IP address? */
    1965         if (is_ipaddress(servername)) {
    1966                 return is_my_ipaddr(servername);
    1967         }
    1968 
    19691595        /* No match */
    19701596        return false;
     
    20521678        return state->ret;
    20531679}
     1680
     1681int poll_one_fd(int fd, int events, int timeout, int *revents)
     1682{
     1683        struct pollfd *fds;
     1684        int ret;
     1685        int saved_errno;
     1686
     1687        fds = TALLOC_ZERO_ARRAY(talloc_tos(), struct pollfd, 2);
     1688        if (fds == NULL) {
     1689                errno = ENOMEM;
     1690                return -1;
     1691        }
     1692        fds[0].fd = fd;
     1693        fds[0].events = events;
     1694
     1695        ret = sys_poll(fds, 1, timeout);
     1696
     1697        /*
     1698         * Assign whatever poll did, even in the ret<=0 case.
     1699         */
     1700        *revents = fds[0].revents;
     1701        saved_errno = errno;
     1702        TALLOC_FREE(fds);
     1703        errno = saved_errno;
     1704
     1705        return ret;
     1706}
     1707
     1708int poll_intr_one_fd(int fd, int events, int timeout, int *revents)
     1709{
     1710        struct pollfd pfd;
     1711        int ret;
     1712
     1713        pfd.fd = fd;
     1714        pfd.events = events;
     1715
     1716        ret = sys_poll_intr(&pfd, 1, timeout);
     1717        if (ret <= 0) {
     1718                *revents = 0;
     1719                return ret;
     1720        }
     1721        *revents = pfd.revents;
     1722        return 1;
     1723}
Note: See TracChangeset for help on using the changeset viewer.