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
     140
     141
     142
     143
     144
    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
     560
    803561                        return status;
    804562                }
     
    876634        }
    877635
     636
     637
     638
     639
     640
     641
     642
     643
     644
     645
     646
     647
     648
     649
     650
     651
     652
     653
     654
     655
     656
     657
     658
     659
     660
     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
     860
     861
     862
     863
     864
     865
     866
     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
     1562
     1563
     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
     1681
     1682
     1683
     1684
     1685
     1686
     1687
     1688
     1689
     1690
     1691
     1692
     1693
     1694
     1695
     1696
     1697
     1698
     1699
     1700
     1701
     1702
     1703
     1704
     1705
     1706
     1707
     1708
     1709
     1710
     1711
     1712
     1713
     1714
     1715
     1716
     1717
     1718
     1719
     1720
     1721
     1722
     1723
Note: See TracChangeset for help on using the changeset viewer.