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 #include <xmlrpc-c/config.h>
00043
00044 #include <stdlib.h>
00045 #include <assert.h>
00046 #include <sys/types.h>
00047 #include <unistd.h>
00048 #include <stdio.h>
00049 #include <string.h>
00050 #include <sys/socket.h>
00051 #include <sys/time.h>
00052 #include <netinet/in.h>
00053 #include <netinet/tcp.h>
00054 #include <netdb.h>
00055 #include <arpa/inet.h>
00056 #include <errno.h>
00057
00058 #if HAVE_SYS_FILIO_H
00059 #include <sys/filio.h>
00060 #endif
00061
00062 #include <sys/ioctl.h>
00063
00064
00065 #include "abyss_xmlrpc_int.h"
00066 #include "abyss_mallocvar.h"
00067 #include "abyss_trace.h"
00068 #include "abyss_socket.h"
00069 #include <xmlrpc-c/abyss.h>
00070
00071 #include "abyss_socket_unix.h"
00072
00073
00074
00075 struct socketUnix {
00076
00077
00078
00079 int fd;
00080
00081
00082
00083 abyss_bool userSuppliedFd;
00084
00085
00086
00087 };
00088
00089
00090 void
00091 SocketUnixInit(abyss_bool * const succeededP) {
00092
00093 *succeededP = TRUE;
00094 }
00095
00096
00097
00098 void
00099 SocketUnixTerm(void) {
00100
00101 }
00102
00103
00104
00105 static SocketDestroyImpl socketDestroy;
00106 static SocketWriteImpl socketWrite;
00107 static SocketReadImpl socketRead;
00108 static SocketConnectImpl socketConnect;
00109 static SocketBindImpl socketBind;
00110 static SocketListenImpl socketListen;
00111 static SocketAcceptImpl socketAccept;
00112 static SocketErrorImpl socketError;
00113 static SocketWaitImpl socketWait;
00114 static SocketAvailableReadBytesImpl socketAvailableReadBytes;
00115 static SocketGetPeerNameImpl socketGetPeerName;
00116
00117
00118 static struct TSocketVtbl const vtbl = {
00119 &socketDestroy,
00120 &socketWrite,
00121 &socketRead,
00122 &socketConnect,
00123 &socketBind,
00124 &socketListen,
00125 &socketAccept,
00126 &socketError,
00127 &socketWait,
00128 &socketAvailableReadBytes,
00129 &socketGetPeerName
00130 };
00131
00132
00133
00134 void
00135 SocketUnixCreate(TSocket ** const socketPP) {
00136
00137 struct socketUnix * socketUnixP;
00138
00139 MALLOCVAR(socketUnixP);
00140
00141 if (socketUnixP) {
00142 int rc;
00143 rc = socket(AF_INET, SOCK_STREAM, 0);
00144 if (rc < 0)
00145 *socketPP = NULL;
00146 else {
00147 socketUnixP->fd = rc;
00148 socketUnixP->userSuppliedFd = FALSE;
00149
00150 {
00151 int32_t n = 1;
00152 int rc;
00153 rc = setsockopt(socketUnixP->fd, SOL_SOCKET, SO_REUSEADDR,
00154 (char*)&n, sizeof(n));
00155 if (rc < 0)
00156 *socketPP = NULL;
00157 else
00158 SocketCreate(&vtbl, socketUnixP, socketPP);
00159 }
00160 if (!*socketPP)
00161 close(socketUnixP->fd);
00162 }
00163 if (!*socketPP)
00164 free(socketUnixP);
00165 } else
00166 *socketPP = NULL;
00167 }
00168
00169
00170
00171 void
00172 SocketUnixCreateFd(int const fd,
00173 TSocket ** const socketPP) {
00174
00175 struct socketUnix * socketUnixP;
00176
00177 MALLOCVAR(socketUnixP);
00178
00179 if (socketUnixP) {
00180 socketUnixP->fd = fd;
00181 socketUnixP->userSuppliedFd = TRUE;
00182
00183 SocketCreate(&vtbl, socketUnixP, socketPP);
00184
00185 if (!*socketPP)
00186 free(socketUnixP);
00187 } else
00188 *socketPP = NULL;
00189 }
00190
00191
00192
00193 static void
00194 socketDestroy(TSocket * const socketP) {
00195
00196 struct socketUnix * const socketUnixP = socketP->implP;
00197
00198 if (!socketUnixP->userSuppliedFd)
00199 close(socketUnixP->fd);
00200
00201 free(socketUnixP);
00202 }
00203
00204
00205
00206 static void
00207 socketWrite(TSocket * const socketP,
00208 const unsigned char * const buffer,
00209 uint32_t const len,
00210 abyss_bool * const failedP) {
00211
00212 struct socketUnix * const socketUnixP = socketP->implP;
00213
00214 size_t bytesLeft;
00215 abyss_bool error;
00216
00217 assert(sizeof(size_t) >= sizeof(len));
00218
00219 for (bytesLeft = len, error = FALSE;
00220 bytesLeft > 0 && !error;
00221 ) {
00222 size_t const maxSend = (size_t)(-1) >> 1;
00223
00224 ssize_t rc;
00225
00226 rc = send(socketUnixP->fd, &buffer[len-bytesLeft],
00227 MIN(maxSend, bytesLeft), 0);
00228
00229 if (SocketTraceIsActive) {
00230 if (rc < 0)
00231 fprintf(stderr, "Abyss socket: send() failed. errno=%d (%s)",
00232 errno, strerror(errno));
00233 else if (rc == 0)
00234 fprintf(stderr, "Abyss socket: send() failed. "
00235 "Socket closed.\n");
00236 else
00237 fprintf(stderr, "Abyss socket: sent %u bytes: '%.*s'\n",
00238 (unsigned int)-rc, (int)-rc, &buffer[len-bytesLeft]);
00239 }
00240 if (rc <= 0)
00241
00242 error = TRUE;
00243 else
00244 bytesLeft -= rc;
00245 }
00246 *failedP = error;
00247 }
00248
00249
00250
00251 static uint32_t
00252 socketRead(TSocket * const socketP,
00253 char * const buffer,
00254 uint32_t const len) {
00255
00256 struct socketUnix * const socketUnixP = socketP->implP;
00257
00258 int rc;
00259 rc = recv(socketUnixP->fd, buffer, len, 0);
00260 if (SocketTraceIsActive) {
00261 if (rc < 0)
00262 fprintf(stderr, "Abyss socket: recv() failed. errno=%d (%s)",
00263 errno, strerror(errno));
00264 else
00265 fprintf(stderr, "Abyss socket: read %u bytes: '%.*s'\n",
00266 len, (int)len, buffer);
00267 }
00268 return rc;
00269 }
00270
00271
00272
00273 abyss_bool
00274 socketConnect(TSocket * const socketP,
00275 TIPAddr * const addrP,
00276 uint16_t const portNumber) {
00277
00278 struct socketUnix * const socketUnixP = socketP->implP;
00279
00280 struct sockaddr_in name;
00281 int rc;
00282
00283 name.sin_family = AF_INET;
00284 name.sin_port = htons(portNumber);
00285 name.sin_addr = *addrP;
00286
00287 rc = connect(socketUnixP->fd, (struct sockaddr *)&name, sizeof(name));
00288
00289 return rc != -1;
00290 }
00291
00292
00293
00294 abyss_bool
00295 socketBind(TSocket * const socketP,
00296 TIPAddr * const addrP,
00297 uint16_t const portNumber) {
00298
00299 struct socketUnix * const socketUnixP = socketP->implP;
00300
00301 struct sockaddr_in name;
00302 int rc;
00303
00304 name.sin_family = AF_INET;
00305 name.sin_port = htons(portNumber);
00306 if (addrP)
00307 name.sin_addr = *addrP;
00308 else
00309 name.sin_addr.s_addr = INADDR_ANY;
00310
00311 rc = bind(socketUnixP->fd, (struct sockaddr *)&name, sizeof(name));
00312
00313 return (rc != -1);
00314 }
00315
00316
00317
00318 abyss_bool
00319 socketListen(TSocket * const socketP,
00320 uint32_t const backlog) {
00321
00322 struct socketUnix * const socketUnixP = socketP->implP;
00323
00324 int32_t const minus1 = -1;
00325
00326 int rc;
00327
00328
00329
00330 setsockopt(socketUnixP->fd, IPPROTO_TCP,TCP_NODELAY,
00331 &minus1, sizeof(minus1));
00332
00333 rc = listen(socketUnixP->fd, backlog);
00334
00335 return (rc != -1);
00336 }
00337
00338
00339
00340 static void
00341 socketAccept(TSocket * const listenSocketP,
00342 abyss_bool * const connectedP,
00343 abyss_bool * const failedP,
00344 TSocket ** const acceptedSocketPP,
00345 TIPAddr * const ipAddrP) {
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 struct socketUnix * const listenSocketUnixP = listenSocketP->implP;
00360
00361 abyss_bool connected, failed, interrupted;
00362
00363 connected = FALSE;
00364 failed = FALSE;
00365 interrupted = FALSE;
00366
00367 while (!connected && !failed && !interrupted) {
00368 struct sockaddr_in sa;
00369 socklen_t size = sizeof(sa);
00370 int rc;
00371 rc = accept(listenSocketUnixP->fd, (struct sockaddr *)&sa, &size);
00372 if (rc >= 0) {
00373 int const acceptedFd = rc;
00374 struct socketUnix * acceptedSocketUnixP;
00375
00376 MALLOCVAR(acceptedSocketUnixP);
00377
00378 if (acceptedSocketUnixP) {
00379 acceptedSocketUnixP->fd = acceptedFd;
00380 acceptedSocketUnixP->userSuppliedFd = FALSE;
00381
00382 SocketCreate(&vtbl, acceptedSocketUnixP, acceptedSocketPP);
00383 if (!*acceptedSocketPP)
00384 failed = TRUE;
00385 else {
00386 connected = TRUE;
00387 *ipAddrP = sa.sin_addr;
00388 }
00389 if (failed)
00390 free(acceptedSocketUnixP);
00391 } else
00392 failed = TRUE;
00393 if (failed)
00394 close(acceptedFd);
00395 } else if (errno == EINTR)
00396 interrupted = TRUE;
00397 else
00398 failed = TRUE;
00399 }
00400 *failedP = failed;
00401 *connectedP = connected;
00402 }
00403
00404
00405
00406 static uint32_t
00407 socketWait(TSocket * const socketP,
00408 abyss_bool const rd,
00409 abyss_bool const wr,
00410 uint32_t const timems) {
00411
00412 struct socketUnix * const socketUnixP = socketP->implP;
00413
00414 fd_set rfds, wfds;
00415 struct timeval tv;
00416
00417 FD_ZERO(&rfds);
00418 FD_ZERO(&wfds);
00419
00420 if (rd)
00421 FD_SET(socketUnixP->fd, &rfds);
00422
00423 if (wr)
00424 FD_SET(socketUnixP->fd, &wfds);
00425
00426 tv.tv_sec = timems / 1000;
00427 tv.tv_usec = timems % 1000;
00428
00429 for (;;) {
00430 int rc;
00431
00432 rc = select(socketUnixP->fd + 1, &rfds, &wfds, NULL,
00433 (timems == TIME_INFINITE ? NULL : &tv));
00434
00435 switch(rc) {
00436 case 0:
00437 return 0;
00438
00439 case -1:
00440 if (errno == EINTR)
00441 break;
00442
00443 return 0;
00444
00445 default:
00446 if (FD_ISSET(socketUnixP->fd, &rfds))
00447 return 1;
00448 if (FD_ISSET(socketUnixP->fd, &wfds))
00449 return 2;
00450 return 0;
00451 }
00452 }
00453 }
00454
00455
00456
00457 static uint32_t
00458 socketAvailableReadBytes(TSocket * const socketP) {
00459
00460 struct socketUnix * const socketUnixP = socketP->implP;
00461
00462 uint32_t x;
00463 int rc;
00464
00465 rc = ioctl(socketUnixP->fd, FIONREAD, &x);
00466
00467 return rc == 0 ? x : 0;
00468 }
00469
00470
00471
00472 static void
00473 socketGetPeerName(TSocket * const socketP,
00474 TIPAddr * const ipAddrP,
00475 uint16_t * const portNumberP,
00476 abyss_bool * const successP) {
00477
00478 struct socketUnix * const socketUnixP = socketP->implP;
00479
00480 socklen_t addrlen;
00481 int rc;
00482 struct sockaddr sockAddr;
00483
00484 addrlen = sizeof(sockAddr);
00485
00486 rc = getpeername(socketUnixP->fd, &sockAddr, &addrlen);
00487
00488 if (rc < 0) {
00489 TraceMsg("getpeername() failed. errno=%d (%s)",
00490 errno, strerror(errno));
00491 *successP = FALSE;
00492 } else {
00493 if (addrlen != sizeof(sockAddr)) {
00494 TraceMsg("getpeername() returned a socket address of the wrong "
00495 "size: %u. Expected %u", addrlen, sizeof(sockAddr));
00496 *successP = FALSE;
00497 } else {
00498 if (sockAddr.sa_family != AF_INET) {
00499 TraceMsg("Socket does not use the Inet (IP) address "
00500 "family. Instead it uses family %d",
00501 sockAddr.sa_family);
00502 *successP = FALSE;
00503 } else {
00504 struct sockaddr_in * const sockAddrInP = (struct sockaddr_in *)
00505 &sockAddr;
00506
00507 *ipAddrP = sockAddrInP->sin_addr;
00508 *portNumberP = sockAddrInP->sin_port;
00509
00510 *successP = TRUE;
00511 }
00512 }
00513 }
00514 }
00515
00516
00517
00518 static uint32_t
00519 socketError(TSocket * const socketP) {
00520
00521 if (socketP){}
00522
00523 return errno;
00524 }