00001
00011
00012
00013 #ifdef HAVE_CONFIG_H
00014 #include "config.h"
00015 #include "gridsolve-config.h"
00016 #endif
00017
00018 #include <signal.h>
00019 #include <errno.h>
00020 #include <string.h>
00021 #ifdef HAVE_STROPTS_H
00022 #include <stropts.h>
00023 #endif
00024 #include <sys/types.h>
00025
00026 #if defined (solaris)
00027 #include <sys/filio.h>
00028 #endif
00029
00030 #include "portability.h"
00031 #include "proxylib.h"
00032 #include "comm_basics.h"
00033 #include "utility.h"
00034
00045 ssize_t
00046 gs_twrite(SOCKET fildes, const void *buf, size_t nbyte)
00047 {
00048 static int sig = 1;
00049 if (sig) {
00050 (void) gs_signal(GS_SIGPIPE, SIG_IGN);
00051 sig = 0;
00052 }
00053 return gs_writen(fildes, buf, nbyte);
00054 }
00055
00056
00070 ssize_t
00071 gs_writen(SOCKET fd, const void *vptr, size_t n)
00072 {
00073 size_t nleft;
00074 ssize_t nwritten;
00075 const char *ptr;
00076
00077 ptr = vptr;
00078 DBGPRINTF("ns_writen: write %d bytes to socket %d num %d char %c\n",
00079 n, fd, *((int *)ptr), (char)*ptr);
00080 nleft = n;
00081 while (nleft > 0) {
00082 if ( (nwritten = write_socket(fd, ptr, nleft)) == SOCKET_ERROR) {
00083 if (errno_socket() == EINTR)
00084 nwritten = 0;
00085 else
00086 return(-1);
00087 }
00088
00089 nleft -= nwritten;
00090 ptr += nwritten;
00091 }
00092 return(n);
00093 }
00094
00105 int
00106 gs_tread(SOCKET d, char *b, int n)
00107 {
00108 static int sig = 1;
00109 int retval = -1;
00110
00111 if (sig) {
00112 (void) gs_signal(GS_SIGPIPE, SIG_IGN);
00113 sig = 0;
00114 }
00115
00116 retval = proxy_tread(d, b, n, PROXY_TIMEOUT_DEFAULT);
00117
00118 return retval;
00119 }
00120
00131 ssize_t
00132 gs_readline(int fd, void *vptr, size_t maxlen)
00133 {
00134 int n, rc;
00135 char c, *ptr;
00136
00137 ptr = vptr;
00138 for (n = 1; n < (int)maxlen; n++) {
00139 if ((rc = proxy_tread(fd, &c, 1, PROXY_TIMEOUT_DEFAULT)) == 1) {
00140 *ptr++ = c;
00141 if (c == '\n')
00142 break;
00143 } else if (rc == 0) {
00144 if (n == 1)
00145 return (0);
00146 else
00147 break;
00148 } else
00149 return (-1);
00150 }
00151
00152 *ptr = 0;
00153 return (n);
00154 }
00155
00169 SOCKET
00170 gs_establish_socket(in_port_t * port, int reuse)
00171 {
00172 SOCKET desc;
00173 struct sockaddr_in addr;
00174 socklen_t addr_length;
00175 int option_value = 1;
00176
00177 if ((desc = proxy_socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
00178 return INVALID_SOCKET;
00179 }
00180
00181
00182 if (reuse) {
00183 if (setsockopt(desc, SOL_SOCKET, SO_REUSEADDR,
00184 (char *) (&option_value), sizeof(int)) == -1) {
00185 return INVALID_SOCKET;
00186 }
00187 }
00188
00189 if(setsockopt(desc, IPPROTO_TCP, TCP_NODELAY, (char *) &option_value,
00190 sizeof(int)) < 0)
00191 DBGPRINTF("Warning: failed to set TCP_NODELAY for fd %d\n", desc);
00192
00193 memset((char *) &addr, 0x0, sizeof(addr));
00194 addr.sin_family = AF_INET;
00195 addr.sin_addr.s_addr = htonl(INADDR_ANY);
00196 addr.sin_port = htons(*port);
00197
00198 if (proxy_bind(desc, (struct sockaddr *) &addr, sizeof(addr))) {
00199 if (errno_socket() == EADDRINUSE) {
00200 proxy_close(desc);
00201 return -2;
00202 }
00203 proxy_close(desc);
00204 return INVALID_SOCKET;
00205 }
00206
00207 addr_length = sizeof(addr);
00208 if((proxy_getsockname(desc, (struct sockaddr *) &addr, &addr_length)) == -1) {
00209 proxy_close(desc);
00210 return INVALID_SOCKET;
00211 }
00212 *port = ntohs(addr.sin_port);
00213
00214 return (desc);
00215 }
00216
00227 SOCKET
00228 gs_bind_to_first_available_port(in_port_t initport, in_port_t * found_port)
00229 {
00230 in_port_t port;
00231 in_port_t tryport;
00232 SOCKET sock;
00233
00234 port = initport;
00235 tryport = port;
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 while ((sock = gs_establish_socket(&tryport, 0)) == -2) {
00248 port++;
00249 tryport = port;
00250 if (port > initport + GS_NUM_PORTS_TO_TRY) {
00251 ERRPRINTF("Impossible to bind to a port\n");
00252 return INVALID_SOCKET;
00253 }
00254 }
00255
00256 if (proxy_is_socket_error(sock))
00257 return INVALID_SOCKET;
00258
00259 *found_port = tryport;
00260
00261 if (*found_port == 0) {
00262 *found_port = initport;
00263 }
00264
00265 return sock;
00266 }
00267
00276 int
00277 gs_listen_on_socket(SOCKET sock)
00278 {
00279 return proxy_listen(sock, PROXY_MAX_CONNECTIONS);
00280 }
00281
00291 int
00292 gs_accept_connection(SOCKET listening_socket)
00293 {
00294 struct sockaddr_in addr;
00295 socklen_t addrlen;
00296 int sock;
00297
00298 addrlen = sizeof(addr);
00299 sock = proxy_accept(listening_socket, (struct sockaddr *) &addr, &addrlen);
00300 while (sock == INVALID_SOCKET && errno_socket() == EINTR) {
00301 sock = proxy_accept(listening_socket, (struct sockaddr *) &addr, &addrlen);
00302 }
00303 return sock;
00304 }
00305
00314 int
00315 gs_close_socket(SOCKET sock)
00316 {
00317 return proxy_close(sock);
00318 }
00319
00334 SOCKET
00335 gs_connect_to_host(char *ID, ipaddr_t ipaddr, int port,
00336 ipaddr_t proxyIP, int proxyPort)
00337 {
00338 PROXY_COMPONENTADDR servaddr;
00339 char dottedip[20];
00340 char dottedproxy[20];
00341 SOCKET sockfd, option_value = 1;
00342
00343 memcpy(servaddr.ID, ID, CID_LEN);
00344
00345 servaddr.IP = ipaddr;
00346 servaddr.port = htons(port);
00347 servaddr.proxyIP = proxyIP;
00348 servaddr.proxyPort = htons(proxyPort);
00349
00350 sockfd = proxy_socket(AF_INET, SOCK_STREAM, 0);
00351
00352 if(setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *) &option_value,
00353 sizeof(int)) < 0)
00354 DBGPRINTF("Warning: failed to set TCP_NODELAY for fd %d\n", sockfd);
00355
00356 proxy_ip_to_str(servaddr.IP, dottedip);
00357 proxy_ip_to_str(servaddr.proxyIP, dottedproxy);
00358 DBGPRINTF("Connecting to %s:%d (proxy %s:%d)\n", dottedip,
00359 ntohs(servaddr.port), dottedproxy, ntohs(servaddr.proxyPort));
00360
00361 if (proxy_connect(sockfd, &servaddr) < 0) {
00362 ERRPRINTF("Could not connect to %s:%d (proxy %s:%d)\n", dottedip,
00363 ntohs(servaddr.port), dottedproxy, ntohs(servaddr.proxyPort));
00364 proxy_close(sockfd);
00365 return INVALID_SOCKET;
00366 }
00367
00368 return sockfd;
00369 }
00370
00380 SOCKET
00381 gs_connect_direct(char *host, int port)
00382 {
00383 char agent_cid[CID_LEN];
00384 struct hostent *hp;
00385 ipaddr_t ipaddr;
00386
00387 DBGPRINTF("Connecting to host %s port %d\n", host, port);
00388
00389 if ((hp = gethostbyname(host)) == NULL) {
00390 errno = errno_socket();
00391 ERRPRINTF("Could not gethostbyname for %s (errno %d) \n", host, errno);
00392 perror("gethostbyname()");
00393 return INVALID_SOCKET;
00394 }
00395
00396 memcpy((void *) &ipaddr, hp->h_addr_list[0], sizeof(ipaddr));
00397
00398
00399 memset(agent_cid, 0xFF, CID_LEN);
00400
00401 return gs_connect_to_host(agent_cid, ipaddr, port, 0, 0);
00402 }