00001
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 #include <stdio.h>
00031 #include <fcntl.h>
00032 #include <string.h>
00033 #include <assert.h>
00034 #include <stdlib.h>
00035 #include <nsnet.h>
00036 #include <nsutil.h>
00037 #include <monitor.h>
00038
00039 #ifndef __MINGW32__
00040 #include <signal.h>
00041 #endif
00042
00043 #define NUM_WRITEN 1
00044 #define NUM_READN 2
00045 #define NUM_MYREAD 3
00046 #define NUM_READLINE 4
00047 #define NUM_WRITEN2 5
00048
00049 #define NUM_MAX 6
00050
00051
00052 #define NUM_QUIET
00053
00054 unsigned int cur[NUM_MAX], last[NUM_MAX];
00055
00056 void addCount(int where)
00057 {
00058 assert(where >= 0 && where < NUM_MAX);
00059 cur[where] += 1;
00060 }
00061
00062 void showCounts()
00063 {
00064 #ifdef NUM_QUIET
00065 return;
00066 #else
00067 int i;
00068
00069 for (i = 0; i < NUM_MAX; ++i)
00070 rprintf("%d:%d\t", i, cur[i]);
00071 rprintf("\n");
00072 #endif
00073 }
00074
00075
00076 int isEOF(sock_t con, const struct InputBuffer *ib)
00077 {
00078 return ib->isEOF;
00079 }
00080
00081 const char *stringifyErrorCode(int code)
00082 {
00083 static char buf[80];
00084 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00085 switch (code) {
00086 case WSAECONNRESET:
00087 return "WSAECONNRESET";
00088 break;
00089 case WSAECONNREFUSED:
00090 return "WSAECONNREFUSED";
00091 break;
00092 case WSAECONNABORTED:
00093 return "WSAECONNABORTED";
00094 break;
00095 case WSAENOTSOCK:
00096 return "WSAENOTSOCK";
00097 break;
00098 case WSAEINVAL:
00099 return "WSAEINVAL";
00100 break;
00101 case WSAEISCONN:
00102 return "WSAEISCONN";
00103 break;
00104 case WSAEALREADY:
00105 return "WSAEALREADY";
00106 break;
00107 case WSAEWOULDBLOCK:
00108 return "WSAEWOULDBLOCK";
00109 break;
00110 case WSAEINPROGRESS:
00111 return "WSAEINPROGRESS";
00112 break;
00113 default:
00114 sprintf(buf, "<unknown win:%d>", code);
00115 return buf;
00116 break;
00117 }
00118 #else
00119 sprintf(buf, "<unknown %s:%d>", OSTYPESTR, code);
00120 return buf;
00121 #endif
00122 }
00123
00124 void rshutdown(sock_t fd)
00125 {
00126 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00127 shutdown(fd, SD_BOTH);
00128 #else
00129 shutdown(fd, SHUT_RDWR);
00130 #endif
00131 }
00132
00133 void setblocking(sock_t sock_fd)
00134 {
00135 int retval;
00136 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00137 do {
00138 u_long val;
00139 val = 0;
00140 retval = ioctlsocket(sock_fd, FIONBIO, &val);
00141 if (retval != 0) {
00142 int winerr;
00143 winerr = WSAGetLastError();
00144 monitorLog(PLACE_SETBLOCKING, winerr);
00145 rexit(1);
00146 }
00147 } while (0);
00148 #else
00149 do {
00150 int flags;
00151 flags = fcntl(sock_fd, F_GETFL, 0);
00152 retval = fcntl(sock_fd, F_SETFL, flags & (~O_NONBLOCK));
00153
00154
00155
00156
00157 } while (0);
00158 #endif
00159 }
00160 void setnonblocking(sock_t sock_fd)
00161 {
00162 int retval;
00163 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00164 do {
00165 u_long val;
00166 val = 1;
00167 retval = ioctlsocket(sock_fd, FIONBIO, &val);
00168 if (retval != 0) {
00169 rprintf("Error setting FIONBIO\n");
00170 rexit(1);
00171 }
00172 } while (0);
00173 #else
00174 do {
00175 int flags;
00176 flags = fcntl(sock_fd, F_GETFL, 0);
00177 retval = fcntl(sock_fd, F_SETFL, flags | O_NONBLOCK);
00178 if (retval != 0) {
00179 rprintf("Error setting O_NONBLOCK\n");
00180 rexit(1);
00181 }
00182 } while (0);
00183 #endif
00184 }
00185
00186 sock_t rsocket(void) {
00187 sock_t sock_fd;
00188 sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
00189 setnonblocking(sock_fd);
00190 return sock_fd;
00191 }
00192
00193 #if 1 || (!defined(__MINGW32__) && !defined(__CYGWIN__))
00194 void sigPIPEHandler(int i) {
00195 }
00196 #endif
00197
00198 int rinitNetworking(void) {
00199 static int mustInit = 1;
00200 if (mustInit) {
00201 mustInit = 0;
00202 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00203 WSADATA wsadata;
00204 WSAStartup(MAKEWORD(2,0), &wsadata);
00205 WSASetLastError(0);
00206 #else
00207 signal(SIGPIPE, sigPIPEHandler);
00208 #endif
00209 }
00210 return 0;
00211 }
00212
00213 int rbindAll(sock_t sock_fd)
00214 {
00215 rsockaddr_t local;
00216 int retval;
00217 int one = 1;
00218
00219 retval = setsockopt(sock_fd,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
00220
00221 if (retval != 0) {
00222 rprintf("setsockopt error\n");
00223 rexit(1);
00224 }
00225
00226 local.sin_family = AF_INET;
00227 local.sin_port = htons(DEFAULTPORT);
00228 local.sin_addr.s_addr = INADDR_ANY;
00229
00230 retval = bind(sock_fd, (struct sockaddr *) &local, sizeof(local));
00231 if (retval != 0) {
00232 rprintf("bind error\n");
00233 rexit(1);
00234 }
00235 retval = listen(sock_fd, MAXCLIENTS);
00236 if (retval != 0) {
00237 rprintf("listen error\n");
00238 rexit(1);
00239 }
00240
00241 return 0;
00242 }
00243
00244 int rconnectName(sock_t sock_fd, const char *hostname, unsigned short portno)
00245 {
00246 int retval;
00247 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00248 int winerr;
00249 #endif
00250 rsockaddr_t local;
00251 hostent_t host;
00252 host = gethostbyname(hostname);
00253 if(host == NULL) {
00254 rprintf("Error looking up %s\n", hostname);
00255 perror("gethostbyname");
00256 rexit(1);
00257 }
00258 local.sin_family = AF_INET;
00259 local.sin_port = htons(portno);
00260 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00261 local.sin_addr = *((LPIN_ADDR)*host->h_addr_list);
00262 #else
00263 local.sin_addr = *((struct in_addr *)host->h_addr);
00264 #endif
00265
00266 rprintf("Connecting to %s at %s:%d\n", hostname, inet_ntoa(local.sin_addr), portno);
00267
00268 while (1) {
00269 retval = connect(sock_fd, (struct sockaddr *) &local, sizeof(local));
00270 if (retval != 0) {
00271 if (errno == EISCONN)
00272 return 0;
00273 else {
00274 if (errno == EINPROGRESS) {
00275 rsleep(5);
00276 continue;
00277 }
00278 perror("moreconnect");
00279 }
00280 }
00281 monitorLog(PLACE_CONNECT, errno);
00282 }
00283 }
00284
00285 sock_t raccept(sock_t sock_fd)
00286 {
00287 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00288 int winerr;
00289 #endif
00290 rsockaddr_t modaddr;
00291 int modaddrsize = sizeof(modaddr);
00292
00293 sock_t retval;
00294
00295 do {
00296 retval = accept(sock_fd, (struct sockaddr *) &modaddr, &modaddrsize);
00297 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00298 if (retval == SOCKET_ERROR) {
00299 winerr = WSAGetLastError();
00300 rprintf("Got error code %s\n", stringifyErrorCode(winerr));
00301 }
00302 } while (retval == SOCKET_ERROR);
00303 #else
00304 } while (retval == -1);
00305 #endif
00306 rprintf("Received new connection from %s\n", inet_ntoa(modaddr.sin_addr));
00307 return retval;
00308 }
00309
00310 int writeString(sock_t con, const char *buf, struct OutputBuffer *ob)
00311 {
00312 return writeBytes(con, buf, strlen(buf), ob);
00313 }
00314
00315 int rrecv(sock_t fd, char *read_buf, size_t count)
00316 {
00317 int retval = -1;
00318 retval = recv(fd, read_buf, count, 0);
00319 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00320 int winerr;
00321 if (retval == SOCKET_ERROR) {
00322 winerr = WSAGetLastError();
00323 if (winerr == WSAEISCONN || winerr == WSAEWOULDBLOCK)
00324 retval = 0;
00325 if (winerr == WSAENOTCONN || winerr == WSAECONNRESET)
00326 retval = -1;
00327 if (retval == -1)
00328 monitorLog(PLACE_RRECV, winerr);
00329 }
00330 #endif
00331 return retval;
00332 }
00333
00334 int writeBytes(sock_t con, const char *buf, int size, struct OutputBuffer *ob)
00335 {
00336 int retval;
00337 char obuf[MAXLEN];
00338 memcpy(obuf, buf, size);
00339 obuf[size] = 0;
00340
00341 setblocking(con);
00342 retval = send(con, buf, size, 0);
00343 setnonblocking(con);
00344 if (retval != size) {
00345 rprintf("send error: %d\n", retval);
00346 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00347 do {
00348 int winerr;
00349 winerr = WSAGetLastError();
00350 monitorLog(PLACE_WRITEBYTES, winerr);
00351 } while (0);
00352 #endif
00353 }
00354 return retval;
00355 }
00356
00357 void initOutputBuffer(struct OutputBuffer *ob)
00358 {
00359 memset(ob, 0, sizeof(*ob));
00360 }
00361
00362 void initInputBuffer(struct InputBuffer *ib)
00363 {
00364 memset(ib, 0, sizeof(*ib));
00365 }
00366
00367 int my_read(sock_t fd, char *ptr, size_t maxlen, struct InputBuffer *ib)
00368 {
00369 addCount(NUM_MYREAD);
00370 showCounts();
00371
00372
00373 if (maxlen == 1) {
00374 rprintf("Inefficient myread(%d)\n", maxlen);
00375 }
00376 if (ib->read_cnt <= 0) {
00377 if ( (ib->read_cnt = rrecv(fd, ib->read_buf, maxlen)) < 0) {
00378 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00379 int winerr;
00380 winerr = WSAGetLastError();
00381 if (winerr != WSAEWOULDBLOCK)
00382 monitorLog(PLACE_MYREAD, winerr);
00383 if (winerr == WSAECONNABORTED || winerr == WSAECONNRESET) {
00384 ib->isEOF = 1;
00385 return -1;
00386 }
00387 if (winerr == WSAEWOULDBLOCK)
00388 return 0;
00389
00390 #else
00391 #endif
00392 return -1;
00393 } else {
00394 if (ib->read_cnt == 0) {
00395 #if defined(__MINGW32__) || defined(__CYGWIN__)
00396 ib->isEOF = 1;
00397 #endif
00398 return 0;
00399 }
00400 }
00401 ib->read_ptr = ib->read_buf;
00402 }
00403
00404 ib->read_cnt--;
00405 *ptr = *ib->read_ptr++;
00406 return 1;
00407 }
00408
00409 size_t readn(sock_t fd, void *vptr, size_t len, struct InputBuffer *ib)
00410 {
00411 size_t nleft;
00412 size_t nread;
00413 char *ptr;
00414 addCount(NUM_READN);
00415 showCounts();
00416 ptr = vptr;
00417 nleft = len;
00418 while (nleft > 0) {
00419 if ( (nread = recv(fd, ptr, nleft, 0)) < 0) {
00420 return -1;
00421 } else if (nread == 0)
00422 break;
00423 nleft -= nread;
00424 ptr += nread;
00425 }
00426 printf("In readn, returning %d\n", len-nleft);
00427 return len - nleft;
00428 }
00429
00430 size_t writen(sock_t fd, const void *vptr, size_t len, struct OutputBuffer *ob)
00431 {
00432 int nleft;
00433 int nwritten;
00434 const char *ptr;
00435 addCount(NUM_WRITEN);
00436 showCounts();
00437
00438 ptr = vptr;
00439 nleft = len;
00440 while (nleft > 0) {
00441 addCount(NUM_WRITEN2);
00442 showCounts();
00443 nwritten = send(fd, ptr, nleft, 0);
00444 if (nwritten <= 0)
00445 return -1;
00446 nleft -= nwritten;
00447 ptr += nwritten;
00448 }
00449 return len;
00450 }
00451
00452 size_t readlinebuf(void **vptrptr, struct InputBuffer *ib)
00453 {
00454 if (ib->read_cnt)
00455 *vptrptr = ib->read_ptr;
00456 return (ib->read_cnt);
00457 }
00458
00459 int inputBufferEmpty(const struct InputBuffer *ib)
00460 {
00461 return ib->read_cnt == 0;
00462 }
00463
00464 int getOK(sock_t sock_fd, struct InputBuffer *ib)
00465 {
00466 int retcode;
00467 rprintf("Waiting for OK\n");
00468 do {
00469 retcode = getResponseCode(sock_fd, ib);
00470 } while (retcode == 0);
00471 if (retcode == -1) {
00472 rprintf("nsnet.o: Server died, exitting.\n");
00473 exit(0);
00474 }
00475 if (retcode != 200) {
00476 printf("Got bad response: %d\n", retcode);
00477 exit(1);
00478 }
00479 return 0;
00480 }
00481
00482 int getResponseCode(sock_t sock_fd, struct InputBuffer *ib)
00483 {
00484 char linebuf[MAXLEN+1];
00485 int len;
00486 do {
00487 len = readline(sock_fd, linebuf, MAXLEN, ib);
00488 } while (len == 0 && !isEOF(sock_fd, ib));
00489 if (isEOF(sock_fd, ib))
00490 return -1;
00491 linebuf[len] = '\0';
00492
00493 strtok(linebuf, " ");
00494 return atoi(linebuf);
00495 }
00496
00497 static int rselect_real(sock_t max_fd, fd_set *toread, fd_set *towrite,
00498 fd_set *toerr,
00499 struct timeval *tv)
00500 {
00501 return select(max_fd, toread,towrite, toerr, tv);
00502 }
00503
00504 int rselect_timed(sock_t max_fd, fd_set *toread, fd_set *towrite,
00505 fd_set *toerr, struct timeval *tv)
00506 {
00507 int retval;
00508 retval = rselect_real(max_fd, toread, towrite, toerr, tv);
00509 return retval;
00510 }
00511
00512 int rselect(sock_t max_fd, fd_set *toread, fd_set *towrite, fd_set *toerr)
00513 {
00514 int retval;
00515
00516 retval = rselect_real(max_fd, toread, towrite, toerr, NULL);
00517 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00518 if (retval == SOCKET_ERROR) {
00519 int winerr;
00520 winerr = WSAGetLastError();
00521 monitorLog(PLACE_RSELECT, winerr);
00522 }
00523 #else
00524 #endif
00525
00526 return retval;
00527 }
00528
00529 int readline(sock_t fd, char *vptr, size_t maxlen, struct InputBuffer *ib)
00530 {
00531 size_t n;
00532 int rc;
00533 char c, *ptr;
00534
00535 addCount(NUM_READLINE);
00536 showCounts();
00537
00538 setblocking(fd);
00539 ptr = vptr;
00540 for (n = 1; n < maxlen; n++) {
00541 rc = my_read(fd, &c, maxlen, ib);
00542 if (rc == -1)
00543 return -1;
00544 if (rc == 0) {
00545 *ptr = 0;
00546 n -= 1;
00547 break;
00548 }
00549 if (rc == 1) {
00550 if (c != '\n' && c != '\r')
00551 *ptr++ = c;
00552 if (c == '\n')
00553 break;
00554 }
00555 }
00556 *ptr = '\0';
00557 return n;
00558 }
00559
00560 #define MAXHANDLER 1024
00561 struct FDHandlerEntry {
00562 sock_t fd;
00563 void (*handler)(void *uobj, const char *data, size_t len);
00564 void *uobj;
00565 };
00566
00567 struct FDHandlerEntry fdTable[MAXHANDLER];
00568 int handlerCount;
00575 int findFdIndex(sock_t fd)
00576 {
00577 int i;
00578 for (i = 0; i < handlerCount; ++i)
00579 if (fdTable[i].fd == fd)
00580 return i;
00581 return -1;
00582 }
00583
00584 int makeNewEntryForFD(sock_t fd, void (*handler)(void *uobj, const char *data, size_t len), void *uobj)
00585 {
00586 int newid = handlerCount;
00587 handlerCount += 1;
00588 if (handlerCount >= MAXHANDLER) {
00589 rprintf("Error: ran out of FD table space at %d\n", handlerCount);
00590 exit(1);
00591 }
00592 fdTable[newid].fd = fd;
00593 fdTable[newid].handler = handler;
00594 fdTable[newid].uobj = uobj;
00595 return newid;
00596 }
00597
00598 int setFdHandler(sock_t fd, void (*handler)(void *uobj, const char *data, size_t len), void *uobj)
00599 {
00600 int id;
00601 id = findFdIndex(fd);
00602 if (id == -1)
00603 id = makeNewEntryForFD(fd, handler, uobj);
00604 else {
00605 fdTable[id].handler = handler;
00606 fdTable[id].uobj = uobj;
00607 }
00608 return 0;
00609 }
00610
00611 int removeFdHandler(sock_t fd)
00612 {
00613 int id;
00614 id = findFdIndex(fd);
00615 if (id == -1)
00616 return 1;
00617 if (id < handlerCount-1)
00618 memmove(&fdTable[id], &fdTable[id+1], (handlerCount-id-1) * sizeof(fdTable[0]));
00619 handlerCount -= 1;
00620 return 0;
00621 }
00622
00623 #define MAXREAD 16384
00624 int handleReads(sock_t fd)
00625 {
00626 int have_read;
00627 char readbuf[MAXREAD];
00628 have_read = rrecv(fd, readbuf, MAXREAD);
00629 if (have_read > 0) {
00630 int id = findFdIndex(fd);
00631 if (id != -1 && fdTable[id].handler != NULL) {
00632 fdTable[id].handler(fdTable[id].uobj, readbuf, have_read);
00633 }
00634
00635 }
00636 return 0;
00637 }