socket.c
上传用户:gzpyjq
上传日期:2013-01-31
资源大小:1852k
文件大小:12k
源码类别:

手机WAP编程

开发平台:

WINDOWS

  1. #include <ctype.h>
  2. #include <errno.h>
  3. #include <stdarg.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <time.h>
  8. #include <unistd.h>
  9. #include <fcntl.h>
  10. #include <sys/time.h>
  11. #include <sys/types.h>
  12. #include <sys/socket.h>
  13. #include <netinet/in.h>
  14. #include <netdb.h>
  15. #include <arpa/inet.h>
  16. #include <sys/utsname.h>
  17. #include "gwlib.h"
  18. static Octstr *official_name = NULL;
  19. static Octstr *official_ip = NULL;
  20. /*
  21.  * FreeBSD is not happy with our approach of allocating a sockaddr
  22.  * and then filling in the fields.  It has private fields that need
  23.  * to be initialized to 0.  This structure is used for that.
  24.  */
  25. static const struct sockaddr_in empty_sockaddr_in;
  26. #ifndef UDP_PACKET_MAX_SIZE
  27. #define UDP_PACKET_MAX_SIZE (64*1024)
  28. #endif
  29. int make_server_socket(int port, const char *interface_name )
  30. {
  31.     struct sockaddr_in addr;
  32.     int s;
  33.     int reuse;
  34.     struct hostent hostinfo;
  35.     s = socket(PF_INET, SOCK_STREAM, 0);
  36.     if (s == -1) {
  37.         error(errno, "socket failed");
  38.         goto error;
  39.     }
  40.     addr = empty_sockaddr_in;
  41.     addr.sin_family = AF_INET;
  42.     addr.sin_port = htons(port);
  43.     if (interface_name == NULL || strcmp(interface_name, "*") == 0)
  44.         addr.sin_addr.s_addr = htonl(INADDR_ANY);
  45.     else {
  46.         if (gw_gethostbyname(&hostinfo, interface_name) == -1) {
  47.             error(errno, "gethostbyname failed");
  48.             goto error;
  49.         }
  50.         addr.sin_addr = *(struct in_addr *) hostinfo.h_addr;
  51.     }
  52.     reuse = 1;
  53.     if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse,
  54.                    sizeof(reuse)) == -1) {
  55.         error(errno, "setsockopt failed for server address");
  56.         goto error;
  57.     }
  58.     if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
  59.         error(errno, "bind failed");
  60.         goto error;
  61.     }
  62.     if (listen(s, 10) == -1) {
  63.         error(errno, "listen failed");
  64.         goto error;
  65.     }
  66.     return s;
  67. error:
  68.     if (s >= 0)
  69.         (void) close(s);
  70.     return -1;
  71. }
  72. int tcpip_connect_to_server(char *hostname, int port, const char *interface_name)
  73. {
  74.     return tcpip_connect_to_server_with_port(hostname, port, 0, interface_name);
  75. }
  76. int tcpip_connect_to_server_with_port(char *hostname, int port, int our_port, const char *interface_name)
  77. {
  78.     struct sockaddr_in addr;
  79.     struct sockaddr_in o_addr;
  80.     struct hostent hostinfo;
  81.     struct hostent o_hostinfo;
  82.     int s;
  83.     s = socket(PF_INET, SOCK_STREAM, 0);
  84.     if (s == -1) {
  85.         error(errno, "Couldn't create new socket.");
  86.         goto error;
  87.     }
  88.     if (gw_gethostbyname(&hostinfo, hostname) == -1) {
  89.         error(errno, "gethostbyname failed");
  90.         goto error;
  91.     }
  92.     addr = empty_sockaddr_in;
  93.     addr.sin_family = AF_INET;
  94.     addr.sin_port = htons(port);
  95.     addr.sin_addr = *(struct in_addr *) hostinfo.h_addr;
  96.     if (our_port > 0 || (interface_name != NULL && strcmp(interface_name, "*") != 0))  {
  97.         int reuse;
  98.         o_addr = empty_sockaddr_in;
  99.         o_addr.sin_family = AF_INET;
  100.         o_addr.sin_port = htons(our_port);
  101. if (interface_name == NULL || strcmp(interface_name, "*") == 0)
  102.     o_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  103. else {
  104.     if (gw_gethostbyname(&o_hostinfo, interface_name) == -1) {
  105. error(errno, "gethostbyname failed");
  106. goto error;
  107.     }
  108.     o_addr.sin_addr = *(struct in_addr *) o_hostinfo.h_addr;
  109. }
  110.         reuse = 1;
  111.         if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse,
  112.                        sizeof(reuse)) == -1) {
  113.             error(errno, "setsockopt failed before bind");
  114.             goto error;
  115.         }
  116.         if (bind(s, (struct sockaddr *) &o_addr, sizeof(o_addr)) == -1) {
  117.             error(errno, "bind to local port %d failed", our_port);
  118.             goto error;
  119.         }
  120.     }
  121.     if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
  122.         error(errno, "connect failed");
  123.         goto error;
  124.     }
  125.     return s;
  126. error:
  127.     error(0, "error connecting to server `%s' at port `%d'",
  128.           hostname, port);
  129.     if (s >= 0)
  130.         close(s);
  131.     return -1;
  132. }
  133. int write_to_socket(int socket, char *str)
  134. {
  135.     size_t len;
  136.     int ret;
  137.     len = strlen(str);
  138.     while (len > 0) {
  139.         ret = write(socket, str, len);
  140.         if (ret == -1) {
  141.             if (errno == EAGAIN) continue;
  142.             if (errno == EINTR) continue;
  143.             error(errno, "Writing to socket failed");
  144.             return -1;
  145.         }
  146.         /* ret may be less than len, if the writing was interrupted
  147.            by a signal. */
  148.         len -= ret;
  149.         str += ret;
  150.     }
  151.     return 0;
  152. }
  153. int socket_set_blocking(int fd, int blocking)
  154. {
  155.     int flags, newflags;
  156.     flags = fcntl(fd, F_GETFL);
  157.     if (flags < 0) {
  158.         error(errno, "cannot get flags for fd %d", fd);
  159.         return -1;
  160.     }
  161.     if (blocking)
  162.         newflags = flags & ~O_NONBLOCK;
  163.     else
  164.         newflags = flags | O_NONBLOCK;
  165.     if (newflags != flags) {
  166.         if (fcntl(fd, F_SETFL, newflags) < 0) {
  167.             error(errno, "cannot set flags for fd %d", fd);
  168.             return -1;
  169.         }
  170.     }
  171.     return 0;
  172. }
  173. int read_available(int fd, long wait_usec)
  174. {
  175.     fd_set rf;
  176.     struct timeval to;
  177.     int ret;
  178.     div_t waits;
  179.     gw_assert(fd >= 0);
  180.     FD_ZERO(&rf);
  181.     FD_SET(fd, &rf);
  182.     waits = div(wait_usec, 1000000);
  183.     to.tv_sec = waits.quot;
  184.     to.tv_usec = waits.rem;
  185. retry:
  186.     ret = select(fd + 1, &rf, NULL, NULL, &to);
  187.     if (ret > 0 && FD_ISSET(fd, &rf))
  188.         return 1;
  189.     if (ret < 0) {
  190.         /* In most select() implementations, to will now contain the
  191.          * remaining time rather than the original time.  That is exactly
  192.          * what we want when retrying after an interrupt. */
  193.         switch (errno) {
  194.             /*The first two entries here are OK*/
  195.         case EINTR:
  196.             goto retry;
  197.         case EAGAIN:
  198.             return 1;
  199.             /* We are now sucking mud, figure things out here
  200.              * as much as possible before it gets lost under
  201.              * layers of abstraction.  */
  202.         case EBADF:
  203.             if (!FD_ISSET(fd, &rf)) {
  204.                 warning(0, "Tried to select on fd %d, not in the set!n", fd);
  205.             } else {
  206.                 warning(0, "Tried to select on invalid fd %d!n", fd);
  207.             }
  208.             break;
  209.         case EINVAL:
  210.             /* Solaris catchall "It didn't work" error, lets apply
  211.              * some tests and see if we can catch it. */
  212.             /* First up, try invalid timeout*/
  213.             if (to.tv_sec > 10000000)
  214.                 warning(0, "Wait more than three years for a select?n");
  215.             if (to.tv_usec > 1000000)
  216.                 warning(0, "There are only 1000000 usec in a second...n");
  217.             break;
  218.         }
  219.         return -1;  /* some error */
  220.     }
  221.     return 0;
  222. }
  223. int udp_client_socket(void)
  224. {
  225.     int s;
  226.     s = socket(PF_INET, SOCK_DGRAM, 0);
  227.     if (s == -1) {
  228.         error(errno, "Couldn't create a UDP socket");
  229.         return -1;
  230.     }
  231.     return s;
  232. }
  233. int udp_bind(int port, const char *interface_name)
  234. {
  235.     int s;
  236.     struct sockaddr_in sa;
  237.     struct hostent hostinfo;
  238.     s = socket(PF_INET, SOCK_DGRAM, 0);
  239.     if (s == -1) {
  240.         error(errno, "Couldn't create a UDP socket");
  241.         return -1;
  242.     }
  243.     sa = empty_sockaddr_in;
  244.     sa.sin_family = AF_INET;
  245.     sa.sin_port = htons(port);
  246.     if (strcmp(interface_name, "*") == 0)
  247.         sa.sin_addr.s_addr = htonl(INADDR_ANY);
  248.     else {
  249.         if (gw_gethostbyname(&hostinfo, interface_name) == -1) {
  250.             error(errno, "gethostbyname failed");
  251.             return -1;
  252.         }
  253.         sa.sin_addr = *(struct in_addr *) hostinfo.h_addr;
  254.     }
  255.     if (bind(s, (struct sockaddr *) &sa, (int) sizeof(sa)) == -1) {
  256.         error(errno, "Couldn't bind a UDP socket to port %d", port);
  257.         (void) close(s);
  258.         return -1;
  259.     }
  260.     return s;
  261. }
  262. Octstr *udp_create_address(Octstr *host_or_ip, int port)
  263. {
  264.     struct sockaddr_in sa;
  265.     struct hostent h;
  266.     sa = empty_sockaddr_in;
  267.     sa.sin_family = AF_INET;
  268.     sa.sin_port = htons(port);
  269.     if (strcmp(octstr_get_cstr(host_or_ip), "*") == 0) {
  270.         sa.sin_addr.s_addr = INADDR_ANY;
  271.     } else {
  272.         if (gw_gethostbyname(&h, octstr_get_cstr(host_or_ip)) == -1) {
  273.             error(0, "Couldn't find the IP number of `%s'",
  274.                   octstr_get_cstr(host_or_ip));
  275.             return NULL;
  276.         }
  277.         sa.sin_addr = *(struct in_addr *) h.h_addr_list[0];
  278.     }
  279.     return octstr_create_from_data((char *) &sa, sizeof(sa));
  280. }
  281. int udp_get_port(Octstr *addr)
  282. {
  283.     struct sockaddr_in sa;
  284.     gw_assert(octstr_len(addr) == sizeof(sa));
  285.     memcpy(&sa, octstr_get_cstr(addr), sizeof(sa));
  286.     return ntohs(sa.sin_port);
  287. }
  288. Octstr *udp_get_ip(Octstr *addr)
  289. {
  290.     struct sockaddr_in sa;
  291.     gw_assert(octstr_len(addr) == sizeof(sa));
  292.     memcpy(&sa, octstr_get_cstr(addr), sizeof(sa));
  293.     return gw_netaddr_to_octstr(AF_INET, &sa.sin_addr);
  294. }
  295. int udp_sendto(int s, Octstr *datagram, Octstr *addr)
  296. {
  297.     struct sockaddr_in sa;
  298.     gw_assert(octstr_len(addr) == sizeof(sa));
  299.     memcpy(&sa, octstr_get_cstr(addr), sizeof(sa));
  300.     if (sendto(s, octstr_get_cstr(datagram), octstr_len(datagram), 0,
  301.                (struct sockaddr *) &sa, (int) sizeof(sa)) == -1) {
  302.         error(errno, "Couldn't send UDP packet");
  303.         return -1;
  304.     }
  305.     return 0;
  306. }
  307. int udp_recvfrom(int s, Octstr **datagram, Octstr **addr)
  308. {
  309.     struct sockaddr_in sa;
  310.     int salen;
  311.     char *buf;
  312.     int bytes;
  313.     buf = gw_malloc(UDP_PACKET_MAX_SIZE);
  314.     salen = sizeof(sa);
  315.     bytes = recvfrom(s, buf, UDP_PACKET_MAX_SIZE, 0,
  316.                      (struct sockaddr *) &sa, &salen);
  317.     if (bytes == -1) {
  318.         if (errno != EAGAIN)
  319.             error(errno, "Couldn't receive UDP packet");
  320. gw_free(buf);
  321.         return -1;
  322.     }
  323.     *datagram = octstr_create_from_data(buf, bytes);
  324.     *addr = octstr_create_from_data((char *) &sa, salen);
  325.     
  326.     gw_free(buf);
  327.     return 0;
  328. }
  329. Octstr *host_ip(struct sockaddr_in addr)
  330. {
  331.     return gw_netaddr_to_octstr(AF_INET, &addr.sin_addr);
  332. }
  333. Octstr *get_official_name(void)
  334. {
  335.     gw_assert(official_name != NULL);
  336.     return official_name;
  337. }
  338. Octstr *get_official_ip(void)
  339. {
  340.     gw_assert(official_ip != NULL);
  341.     return official_ip;
  342. }
  343. static void setup_official_name(void)
  344. {
  345.     struct utsname u;
  346.     struct hostent h;
  347.     gw_assert(official_name == NULL);
  348.     if (uname(&u) == -1)
  349.         panic(0, "uname failed - can't happen, unless " GW_NAME " is buggy.");
  350.     if (gw_gethostbyname(&h, u.nodename) == -1) {
  351.         error(0, "Can't find out official hostname for this host, "
  352.               "using `%s' instead.", u.nodename);
  353.         official_name = octstr_create(u.nodename);
  354. official_ip = octstr_create("127.0.0.1");
  355.     } else {
  356.         official_name = octstr_create(h.h_name);
  357. official_ip = gw_netaddr_to_octstr(AF_INET, h.h_addr);
  358.     }
  359. }
  360. void socket_init(void)
  361. {
  362.     setup_official_name();
  363. }
  364. void socket_shutdown(void)
  365. {
  366.     octstr_destroy(official_name);
  367.     official_name = NULL;
  368.     octstr_destroy(official_ip);
  369.     official_ip = NULL;
  370. }
  371. static Octstr *gw_netaddr_to_octstr4(unsigned char *src)
  372. {
  373.     return octstr_format("%d.%d.%d.%d", src[0], src[1], src[2], src[3]);
  374. }
  375. #ifdef AF_INET6
  376. static Octstr *gw_netaddr_to_octstr6(unsigned char *src)
  377. {
  378.     return octstr_format(
  379.      "%x:%x:%x:%x:"
  380. "%x:%x:%x:%x:"
  381. "%x:%x:%x:%x:"
  382. "%x:%x:%x:%x",
  383.          src[0],  src[1],  src[2],  src[3], 
  384.  src[4],  src[5],  src[6],  src[7], 
  385.  src[8],  src[9], src[10], src[11], 
  386. src[12], src[13], src[14], src[15]);
  387. }
  388. #endif
  389. Octstr *gw_netaddr_to_octstr(int af, void *src)
  390. {
  391.     switch (af) {
  392.     case AF_INET:
  393. return gw_netaddr_to_octstr4(src);
  394. #ifdef AF_INET6
  395.     case AF_INET6:
  396. return gw_netaddr_to_octstr6(src);
  397. #endif
  398.     default:
  399. return NULL;
  400.     } 
  401. }
  402. int gw_accept(int fd, Octstr **client_addr)
  403. {
  404.     struct sockaddr_in addr;
  405.     int addrlen;
  406.     int new_fd;
  407.     if (gwthread_pollfd(fd, POLLIN, -1.0) != POLLIN) {
  408. debug("gwlib.socket", 0, "gwthread_pollfd interrupted or failed");
  409. return -1;
  410.     }
  411.     addrlen = sizeof(addr);
  412.     new_fd = accept(fd, (struct sockaddr *) &addr, &addrlen);
  413.     if (new_fd == -1) {
  414. error(errno, "accept system call failed.");
  415. return -1;
  416.     }
  417.     *client_addr = host_ip(addr);
  418.     debug("test_smsc", 0, "accept() succeeded, client from %s",
  419.   octstr_get_cstr(*client_addr));
  420.     return new_fd;
  421. }