00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #include <ctype.h>
00058 #include <errno.h>
00059 #include <stdarg.h>
00060 #include <stdio.h>
00061 #include <stdlib.h>
00062 #include <string.h>
00063 #include <time.h>
00064 #include <unistd.h>
00065 #include <fcntl.h>
00066
00067 #include <sys/time.h>
00068 #include <sys/types.h>
00069 #include <sys/socket.h>
00070 #include <netinet/in.h>
00071 #include <netdb.h>
00072 #include <arpa/inet.h>
00073 #include <sys/utsname.h>
00074
00075 #include "gwlib.h"
00076
00077
00078 static Octstr *official_name = NULL;
00079 static Octstr *official_ip = NULL;
00080
00081
00082
00083
00084
00085
00086 static const struct sockaddr_in empty_sockaddr_in;
00087
00088 #ifndef UDP_PACKET_MAX_SIZE
00089 #define UDP_PACKET_MAX_SIZE (64*1024)
00090 #endif
00091
00092
00093 int make_server_socket(int port, const char *interface_name )
00094 {
00095 struct sockaddr_in addr;
00096 int s;
00097 int reuse;
00098 struct hostent hostinfo;
00099 char *buff = NULL;
00100
00101 s = socket(PF_INET, SOCK_STREAM, 0);
00102 if (s == -1) {
00103 error(errno, "socket failed");
00104 goto error;
00105 }
00106
00107 addr = empty_sockaddr_in;
00108 addr.sin_family = AF_INET;
00109 addr.sin_port = htons(port);
00110 if (interface_name == NULL || strcmp(interface_name, "*") == 0)
00111 addr.sin_addr.s_addr = htonl(INADDR_ANY);
00112 else {
00113 if (gw_gethostbyname(&hostinfo, interface_name, &buff) == -1) {
00114 error(errno, "gethostbyname failed");
00115 goto error;
00116 }
00117 addr.sin_addr = *(struct in_addr *) hostinfo.h_addr;
00118 }
00119
00120 reuse = 1;
00121 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse,
00122 sizeof(reuse)) == -1) {
00123 error(errno, "setsockopt failed for server address");
00124 goto error;
00125 }
00126
00127 if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
00128 error(errno, "bind failed");
00129 goto error;
00130 }
00131
00132 if (listen(s, 10) == -1) {
00133 error(errno, "listen failed");
00134 goto error;
00135 }
00136
00137 gw_free(buff);
00138
00139 return s;
00140
00141 error:
00142 if (s >= 0)
00143 (void) close(s);
00144 gw_free(buff);
00145 return -1;
00146 }
00147
00148
00149 int tcpip_connect_to_server(char *hostname, int port, const char *interface_name)
00150 {
00151
00152 return tcpip_connect_to_server_with_port(hostname, port, 0, interface_name);
00153 }
00154
00155
00156 int tcpip_connect_to_server_with_port(char *hostname, int port, int our_port, const char *interface_name)
00157 {
00158 struct sockaddr_in addr;
00159 struct sockaddr_in o_addr;
00160 struct hostent hostinfo;
00161 struct hostent o_hostinfo;
00162 int s;
00163 char *buff, *buff1;
00164
00165 buff = buff1 = NULL;
00166
00167 s = socket(PF_INET, SOCK_STREAM, 0);
00168 if (s == -1) {
00169 error(errno, "Couldn't create new socket.");
00170 goto error;
00171 }
00172
00173 if (gw_gethostbyname(&hostinfo, hostname, &buff) == -1) {
00174 error(errno, "gethostbyname failed");
00175 goto error;
00176 }
00177
00178 addr = empty_sockaddr_in;
00179 addr.sin_family = AF_INET;
00180 addr.sin_port = htons(port);
00181 addr.sin_addr = *(struct in_addr *) hostinfo.h_addr;
00182
00183 if (our_port > 0 || (interface_name != NULL && strcmp(interface_name, "*") != 0)) {
00184 int reuse;
00185
00186 o_addr = empty_sockaddr_in;
00187 o_addr.sin_family = AF_INET;
00188 o_addr.sin_port = htons(our_port);
00189 if (interface_name == NULL || strcmp(interface_name, "*") == 0)
00190 o_addr.sin_addr.s_addr = htonl(INADDR_ANY);
00191 else {
00192 if (gw_gethostbyname(&o_hostinfo, interface_name, &buff1) == -1) {
00193 error(errno, "gethostbyname failed");
00194 goto error;
00195 }
00196 o_addr.sin_addr = *(struct in_addr *) o_hostinfo.h_addr;
00197 }
00198
00199 reuse = 1;
00200 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse,
00201 sizeof(reuse)) == -1) {
00202 error(errno, "setsockopt failed before bind");
00203 goto error;
00204 }
00205 if (bind(s, (struct sockaddr *) &o_addr, sizeof(o_addr)) == -1) {
00206 error(errno, "bind to local port %d failed", our_port);
00207 goto error;
00208 }
00209 }
00210
00211 if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
00212 error(errno, "connect failed");
00213 goto error;
00214 }
00215
00216 gw_free(buff);
00217 gw_free(buff1);
00218 return s;
00219
00220 error:
00221 error(0, "error connecting to server `%s' at port `%d'",
00222 hostname, port);
00223 if (s >= 0)
00224 close(s);
00225 gw_free(buff);
00226 gw_free(buff1);
00227 return -1;
00228 }
00229
00230 int tcpip_connect_nb_to_server(char *hostname, int port, const char *interface_name, int *done)
00231 {
00232 return tcpip_connect_nb_to_server_with_port(hostname, port, 0, interface_name, done);
00233 }
00234
00235 int tcpip_connect_nb_to_server_with_port(char *hostname, int port, int our_port, const char *interface_name, int *done)
00236 {
00237 struct sockaddr_in addr;
00238 struct sockaddr_in o_addr;
00239 struct hostent hostinfo;
00240 struct hostent o_hostinfo;
00241 int s;
00242 int flags,rc;
00243 char *buff, *buff1;
00244
00245 *done = 1;
00246 buff = buff1 = NULL;
00247
00248 s = socket(PF_INET, SOCK_STREAM, 0);
00249 if (s == -1) {
00250 error(errno, "Couldn't create new socket.");
00251 goto error;
00252 }
00253
00254 if (gw_gethostbyname(&hostinfo, hostname, &buff) == -1) {
00255 error(errno, "gethostbyname failed");
00256 goto error;
00257 }
00258
00259 addr = empty_sockaddr_in;
00260 addr.sin_family = AF_INET;
00261 addr.sin_port = htons(port);
00262 addr.sin_addr = *(struct in_addr *) hostinfo.h_addr;
00263
00264 if (our_port > 0 || (interface_name != NULL && strcmp(interface_name, "*") != 0)) {
00265 int reuse;
00266
00267 o_addr = empty_sockaddr_in;
00268 o_addr.sin_family = AF_INET;
00269 o_addr.sin_port = htons(our_port);
00270 if (interface_name == NULL || strcmp(interface_name, "*") == 0)
00271 o_addr.sin_addr.s_addr = htonl(INADDR_ANY);
00272 else {
00273 if (gw_gethostbyname(&o_hostinfo, interface_name, &buff1) == -1) {
00274 error(errno, "gethostbyname failed");
00275 goto error;
00276 }
00277 o_addr.sin_addr = *(struct in_addr *) o_hostinfo.h_addr;
00278 }
00279
00280 reuse = 1;
00281 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse,
00282 sizeof(reuse)) == -1) {
00283 error(errno, "setsockopt failed before bind");
00284 goto error;
00285 }
00286 if (bind(s, (struct sockaddr *) &o_addr, sizeof(o_addr)) == -1) {
00287 error(errno, "bind to local port %d failed", our_port);
00288 goto error;
00289 }
00290 }
00291
00292 flags = fcntl(s, F_GETFL, 0);
00293 fcntl(s, F_SETFL, flags | O_NONBLOCK);
00294
00295 if ((rc = connect(s, (struct sockaddr *) &addr, sizeof(addr))) < 0) {
00296 if (errno != EINPROGRESS) {
00297 error(errno, "nonblocking connect failed");
00298 goto error;
00299 }
00300 }
00301
00302
00303
00304 if (rc == 0) {
00305 *done = 0;
00306 }
00307
00308 gw_free(buff);
00309 gw_free(buff1);
00310
00311 return s;
00312
00313 error:
00314 error(0, "error connecting to server `%s' at port `%d'",
00315 hostname, port);
00316 if (s >= 0)
00317 close(s);
00318 gw_free(buff);
00319 gw_free(buff1);
00320 return -1;
00321 }
00322
00323
00324 int write_to_socket(int socket, char *str)
00325 {
00326 size_t len;
00327 int ret;
00328
00329 len = strlen(str);
00330 while (len > 0) {
00331 ret = write(socket, str, len);
00332 if (ret == -1) {
00333 if (errno == EAGAIN) continue;
00334 if (errno == EINTR) continue;
00335 error(errno, "Writing to socket failed");
00336 return -1;
00337 }
00338
00339
00340 len -= ret;
00341 str += ret;
00342 }
00343 return 0;
00344 }
00345
00346
00347 int socket_set_blocking(int fd, int blocking)
00348 {
00349 int flags, newflags;
00350
00351 flags = fcntl(fd, F_GETFL);
00352 if (flags < 0) {
00353 error(errno, "cannot get flags for fd %d", fd);
00354 return -1;
00355 }
00356
00357 if (blocking)
00358 newflags = flags & ~O_NONBLOCK;
00359 else
00360 newflags = flags | O_NONBLOCK;
00361
00362 if (newflags != flags) {
00363 if (fcntl(fd, F_SETFL, newflags) < 0) {
00364 error(errno, "cannot set flags for fd %d", fd);
00365 return -1;
00366 }
00367 }
00368
00369 return 0;
00370 }
00371
00372
00373 int read_available(int fd, long wait_usec)
00374 {
00375 fd_set rf;
00376 struct timeval to;
00377 int ret;
00378 div_t waits;
00379
00380 gw_assert(fd >= 0);
00381
00382 FD_ZERO(&rf);
00383 FD_SET(fd, &rf);
00384 waits = div(wait_usec, 1000000);
00385 to.tv_sec = waits.quot;
00386 to.tv_usec = waits.rem;
00387 retry:
00388 ret = select(fd + 1, &rf, NULL, NULL, &to);
00389 if (ret > 0 && FD_ISSET(fd, &rf))
00390 return 1;
00391 if (ret < 0) {
00392
00393
00394
00395 switch (errno) {
00396
00397 case EINTR:
00398 goto retry;
00399 case EAGAIN:
00400 return 1;
00401
00402
00403
00404 case EBADF:
00405 if (!FD_ISSET(fd, &rf)) {
00406 warning(0, "Tried to select on fd %d, not in the set!\n", fd);
00407 } else {
00408 warning(0, "Tried to select on invalid fd %d!\n", fd);
00409 }
00410 break;
00411 case EINVAL:
00412
00413
00414
00415
00416 if (to.tv_sec > 10000000)
00417 warning(0, "Wait more than three years for a select?\n");
00418 if (to.tv_usec > 1000000)
00419 warning(0, "There are only 1000000 usec in a second...\n");
00420 break;
00421
00422
00423 }
00424 return -1;
00425 }
00426 return 0;
00427 }
00428
00429
00430
00431 int udp_client_socket(void)
00432 {
00433 int s;
00434
00435 s = socket(PF_INET, SOCK_DGRAM, 0);
00436 if (s == -1) {
00437 error(errno, "Couldn't create a UDP socket");
00438 return -1;
00439 }
00440
00441 return s;
00442 }
00443
00444
00445 int udp_bind(int port, const char *interface_name)
00446 {
00447 int s;
00448 struct sockaddr_in sa;
00449 struct hostent hostinfo;
00450 char *buff = NULL;
00451
00452 s = socket(PF_INET, SOCK_DGRAM, 0);
00453 if (s == -1) {
00454 error(errno, "Couldn't create a UDP socket");
00455 return -1;
00456 }
00457
00458 sa = empty_sockaddr_in;
00459 sa.sin_family = AF_INET;
00460 sa.sin_port = htons(port);
00461 if (strcmp(interface_name, "*") == 0)
00462 sa.sin_addr.s_addr = htonl(INADDR_ANY);
00463 else {
00464 if (gw_gethostbyname(&hostinfo, interface_name, &buff) == -1) {
00465 error(errno, "gethostbyname failed");
00466 gw_free(buff);
00467 return -1;
00468 }
00469 sa.sin_addr = *(struct in_addr *) hostinfo.h_addr;
00470 }
00471
00472 if (bind(s, (struct sockaddr *) &sa, (int) sizeof(sa)) == -1) {
00473 error(errno, "Couldn't bind a UDP socket to port %d", port);
00474 (void) close(s);
00475 return -1;
00476 }
00477
00478 gw_free(buff);
00479
00480 return s;
00481 }
00482
00483
00484 Octstr *udp_create_address(Octstr *host_or_ip, int port)
00485 {
00486 struct sockaddr_in sa;
00487 struct hostent h;
00488 char *buff = NULL;
00489 Octstr *ret;
00490
00491 sa = empty_sockaddr_in;
00492 sa.sin_family = AF_INET;
00493 sa.sin_port = htons(port);
00494
00495 if (strcmp(octstr_get_cstr(host_or_ip), "*") == 0) {
00496 sa.sin_addr.s_addr = INADDR_ANY;
00497 } else {
00498 if (gw_gethostbyname(&h, octstr_get_cstr(host_or_ip), &buff) == -1) {
00499 error(0, "Couldn't find the IP number of `%s'",
00500 octstr_get_cstr(host_or_ip));
00501 gw_free(buff);
00502 return NULL;
00503 }
00504 sa.sin_addr = *(struct in_addr *) h.h_addr;
00505 }
00506
00507 ret = octstr_create_from_data((char *) &sa, sizeof(sa));
00508 gw_free(buff);
00509
00510 return ret;
00511 }
00512
00513
00514 int udp_get_port(Octstr *addr)
00515 {
00516 struct sockaddr_in sa;
00517
00518 gw_assert(octstr_len(addr) == sizeof(sa));
00519 memcpy(&sa, octstr_get_cstr(addr), sizeof(sa));
00520 return ntohs(sa.sin_port);
00521 }
00522
00523
00524 Octstr *udp_get_ip(Octstr *addr)
00525 {
00526 struct sockaddr_in sa;
00527
00528 gw_assert(octstr_len(addr) == sizeof(sa));
00529 memcpy(&sa, octstr_get_cstr(addr), sizeof(sa));
00530 return gw_netaddr_to_octstr(AF_INET, &sa.sin_addr);
00531 }
00532
00533
00534 int udp_sendto(int s, Octstr *datagram, Octstr *addr)
00535 {
00536 struct sockaddr_in sa;
00537
00538 gw_assert(octstr_len(addr) == sizeof(sa));
00539 memcpy(&sa, octstr_get_cstr(addr), sizeof(sa));
00540 if (sendto(s, octstr_get_cstr(datagram), octstr_len(datagram), 0,
00541 (struct sockaddr *) &sa, (int) sizeof(sa)) == -1) {
00542 error(errno, "Couldn't send UDP packet");
00543 return -1;
00544 }
00545 return 0;
00546 }
00547
00548
00549 int udp_recvfrom(int s, Octstr **datagram, Octstr **addr)
00550 {
00551 struct sockaddr_in sa;
00552 int salen;
00553 char *buf;
00554 int bytes;
00555
00556 buf = gw_malloc(UDP_PACKET_MAX_SIZE);
00557
00558 salen = sizeof(sa);
00559 bytes = recvfrom(s, buf, UDP_PACKET_MAX_SIZE, 0,
00560 (struct sockaddr *) &sa, &salen);
00561 if (bytes == -1) {
00562 if (errno != EAGAIN)
00563 error(errno, "Couldn't receive UDP packet");
00564 gw_free(buf);
00565 return -1;
00566 }
00567
00568 *datagram = octstr_create_from_data(buf, bytes);
00569 *addr = octstr_create_from_data((char *) &sa, salen);
00570
00571 gw_free(buf);
00572
00573 return 0;
00574 }
00575
00576
00577 Octstr *host_ip(struct sockaddr_in addr)
00578 {
00579 return gw_netaddr_to_octstr(AF_INET, &addr.sin_addr);
00580 }
00581
00582
00583 int host_port(struct sockaddr_in addr)
00584 {
00585 return ntohs(addr.sin_port);
00586 }
00587
00588
00589 Octstr *get_official_name(void)
00590 {
00591 gw_assert(official_name != NULL);
00592 return official_name;
00593 }
00594
00595
00596 Octstr *get_official_ip(void)
00597 {
00598 gw_assert(official_ip != NULL);
00599 return official_ip;
00600 }
00601
00602
00603 static void setup_official_name(void)
00604 {
00605 struct utsname u;
00606 struct hostent h;
00607 char *buff = NULL;
00608
00609 gw_assert(official_name == NULL);
00610 if (uname(&u) == -1)
00611 panic(0, "uname failed - can't happen, unless " GW_NAME " is buggy.");
00612 if (gw_gethostbyname(&h, u.nodename, &buff) == -1) {
00613 error(0, "Can't find out official hostname for this host, "
00614 "using `%s' instead.", u.nodename);
00615 official_name = octstr_create(u.nodename);
00616 official_ip = octstr_create("127.0.0.1");
00617 } else {
00618 official_name = octstr_create(h.h_name);
00619 official_ip = gw_netaddr_to_octstr(AF_INET, h.h_addr);
00620 }
00621 gw_free(buff);
00622 }
00623
00624
00625 void socket_init(void)
00626 {
00627 setup_official_name();
00628 }
00629
00630 void socket_shutdown(void)
00631 {
00632 octstr_destroy(official_name);
00633 official_name = NULL;
00634 octstr_destroy(official_ip);
00635 official_ip = NULL;
00636 }
00637
00638
00639 static Octstr *gw_netaddr_to_octstr4(unsigned char *src)
00640 {
00641 return octstr_format("%d.%d.%d.%d", src[0], src[1], src[2], src[3]);
00642 }
00643
00644
00645 #ifdef AF_INET6
00646 static Octstr *gw_netaddr_to_octstr6(unsigned char *src)
00647 {
00648 return octstr_format(
00649 "%x:%x:%x:%x:"
00650 "%x:%x:%x:%x:"
00651 "%x:%x:%x:%x:"
00652 "%x:%x:%x:%x",
00653 src[0], src[1], src[2], src[3],
00654 src[4], src[5], src[6], src[7],
00655 src[8], src[9], src[10], src[11],
00656 src[12], src[13], src[14], src[15]);
00657 }
00658 #endif
00659
00660 Octstr *gw_netaddr_to_octstr(int af, void *src)
00661 {
00662 switch (af) {
00663 case AF_INET:
00664 return gw_netaddr_to_octstr4(src);
00665
00666 #ifdef AF_INET6
00667 case AF_INET6:
00668 return gw_netaddr_to_octstr6(src);
00669 #endif
00670
00671 default:
00672 return NULL;
00673 }
00674 }
00675
00676
00677 int gw_accept(int fd, Octstr **client_addr)
00678 {
00679 struct sockaddr_in addr;
00680 int addrlen;
00681 int new_fd;
00682
00683 if (gwthread_pollfd(fd, POLLIN, -1.0) != POLLIN) {
00684 debug("gwlib.socket", 0, "gwthread_pollfd interrupted or failed");
00685 return -1;
00686 }
00687 addrlen = sizeof(addr);
00688 new_fd = accept(fd, (struct sockaddr *) &addr, &addrlen);
00689 if (new_fd == -1) {
00690 error(errno, "accept system call failed.");
00691 return -1;
00692 }
00693 *client_addr = host_ip(addr);
00694 debug("test_smsc", 0, "accept() succeeded, client from %s",
00695 octstr_get_cstr(*client_addr));
00696 return new_fd;
00697 }
See file LICENSE for details about the license agreement for using,
modifying, copying or deriving work from this software.