00001 #include <malloc.h>
00002 #include <unistd.h>
00003 #include <stdio.h>
00004 #include <errno.h>
00005 #include <stdlib.h>
00006 #include <string.h>
00007 #include <nsnet.h>
00008 #include <fcntl.h>
00009 #include <assert.h>
00010 #include <neuro/neuro.h>
00011 #include <neuro/ns2net.h>
00012
00013 struct NSNetConnectionController {
00014 struct NSNet *ns;
00015 void *udata;
00016 rsockaddr_t peer;
00017 sock_t fd;
00018 };
00019
00020 struct NSNetReadHandlerInternal {
00021 struct NSNet *ns;
00022 sock_t fd;
00023 void *udata;
00024 struct NSNetConnectionReadHandler nsrh;
00025 };
00026
00027 struct NSNetBindHandlerInternal {
00028 struct NSNet *ns;
00029 sock_t fd;
00030 void *udata;
00031 struct NSNetBindHandler nsb;
00032 };
00033
00034 struct NSNetConnectionHandlerInternal {
00035 struct NSNet *ns;
00036 sock_t fd;
00037 void *udata;
00038 struct NSNetConnectionHandler nsc;
00039 rsockaddr_t dest;
00040 struct NSNetConnectionController nscc;
00041 };
00042
00043 #define MAXCONN 256
00044
00049 struct NSNet {
00050 sock_t max_fd;
00051 fd_set readfds, writefds, errfds;
00052 int NSCICount;
00053 struct StringTable *connectMap;
00054 struct StringTable *bindMap;
00055 struct StringTable *readerMap;
00056 };
00057
00058 static void addWriteFd(struct NSNet *ns, sock_t fd);
00059 static void addReadFd(struct NSNet *ns, sock_t fd);
00060 static void addErrFd(struct NSNet *ns, sock_t fd);
00061
00062 int attachConnectionReadHandler(struct NSNetConnectionController *nscc,
00063 const struct NSNetConnectionReadHandler *nscch, void *udata)
00064 {
00065 struct NSNet *ns;
00066 struct NSNetReadHandlerInternal *newReader;
00067 ns = nscc->ns;
00068 newReader = (struct NSNetReadHandlerInternal *)calloc(sizeof(*newReader),1);
00069 newReader->nsrh = *nscch;
00070 newReader->udata = udata;
00071 newReader->fd = nscc->fd;
00072 newReader->ns = ns;
00073 putInt(ns->readerMap, nscc->fd, newReader);
00074 addReadFd(ns, nscc->fd);
00075 return 0;
00076 }
00077
00078 int attemptBind(struct NSNet *ns, const struct NSNetBindHandler *nsb,
00079 int isLocalOnly, unsigned short portNum, void *udata)
00080 {
00081 struct NSNetBindHandlerInternal *bindHI;
00082
00083 sock_t sock_fd;
00084 rsockaddr_t local;
00085 int retval;
00086 int one = 1;
00087
00088 sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
00089 if (sock_fd < 0) {
00090 perror("socket");
00091 nsb->error(udata);
00092 return 1;
00093 }
00094 retval = setsockopt(sock_fd,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
00095
00096 if (retval != 0) {
00097 perror("setsockopt");
00098 nsb->error(udata);
00099 return 1;
00100 }
00101
00102 local.sin_family = AF_INET;
00103 local.sin_port = htons(portNum);
00104 if (isLocalOnly) {
00105 retval = inet_aton("127.0.0.1", &local.sin_addr);
00106 if (retval == 0) {
00107 perror("inet_aton");
00108 nsb->error(udata);
00109 return 1;
00110 }
00111 }
00112 else
00113 local.sin_addr.s_addr = INADDR_ANY;
00114
00115 retval = bind(sock_fd, (struct sockaddr *) &local, sizeof(local));
00116 if (retval != 0) {
00117 perror("bind");
00118 nsb->error(udata);
00119 return 1;
00120 }
00121 retval = listen(sock_fd, MAXCLIENTS);
00122 if (retval != 0) {
00123 perror("listen");
00124 nsb->error(udata);
00125 return 1;
00126 }
00127
00128 addErrFd(ns, sock_fd);
00129 addReadFd(ns, sock_fd);
00130
00131 bindHI = calloc(sizeof(*bindHI), 1);
00132 bindHI->fd = sock_fd;
00133 bindHI->udata = udata;
00134 bindHI->nsb = *nsb;
00135
00136 putInt(ns->bindMap, sock_fd, bindHI);
00137
00138 return 0;
00139 }
00140
00141 int setNSnonblocking(struct NSNet *ns, sock_t sock_fd)
00142 {
00143 int flags, retval;
00144 flags = fcntl(sock_fd, F_GETFL, 0);
00145 retval = fcntl(sock_fd, F_SETFL, flags | O_NONBLOCK);
00146 assert(retval == 0 && "Error setting O_NONBLOCK\n");
00147 return 0;
00148 }
00149
00150 static void updateNSNetMaxFd(struct NSNet *ns, sock_t fd)
00151 {
00152 if (ns->max_fd < fd+1)
00153 ns->max_fd = fd+1;
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 static int makeAddress(const char *name, unsigned short portNo, rsockaddr_t *result, const struct NSNetConnectionHandler *nsc, void *udata)
00165 {
00166 hostent_t host;
00167 host = gethostbyname(name);
00168 if(host == NULL) {
00169 nsc->unknownHost(udata);
00170 return 1;
00171 }
00172 result->sin_family = AF_INET;
00173 result->sin_port = htons(portNo);
00174 result->sin_addr = *((struct in_addr *)host->h_addr);
00175 return 0;
00176 }
00177
00178 static void addWriteFd(struct NSNet *ns, sock_t fd)
00179 {
00180 FD_SET(fd, &ns->writefds);
00181 updateNSNetMaxFd(ns, fd);
00182 }
00183
00184 static void addErrFd(struct NSNet *ns, sock_t fd)
00185 {
00186 FD_SET(fd, &ns->errfds);
00187 updateNSNetMaxFd(ns, fd);
00188 }
00189
00190 static void addReadFd(struct NSNet *ns, sock_t fd)
00191 {
00192 FD_SET(fd, &ns->readfds);
00193 updateNSNetMaxFd(ns, fd);
00194 }
00195
00196 static void removeFdAll(struct NSNet *ns, sock_t fd)
00197 {
00198 FD_CLR(fd, &ns->readfds);
00199 FD_CLR(fd, &ns->writefds);
00200 FD_CLR(fd, &ns->errfds);
00201 }
00202
00203 int attemptConnect(struct NSNet *ns, const struct NSNetConnectionHandler *nsc,
00204 const char *destaddr, unsigned short destPort, void *udata)
00205 {
00206 int retval;
00207 int connErrno = 0;
00208 sock_t fd;
00209 rsockaddr_t dest;
00210 if (makeAddress(destaddr, destPort, &dest, nsc, udata)) {
00211 return 1;
00212 }
00213 fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
00214 setNSnonblocking(ns, fd);
00215 errno = 0;
00216 retval = connect(fd, (struct sockaddr *) &dest, sizeof(dest));
00217 if (retval == -1) connErrno = errno;
00218 if (retval == 0) {
00219 struct NSNetConnectionController *nscc = calloc(sizeof(*nscc), 1);
00220 nscc->ns = ns;
00221 nscc->fd = fd;
00222 nscc->peer = dest;
00223 nscc->udata = udata;
00224 nsc->success(udata, nscc);
00225
00226 return 0;
00227 }
00228 rassert(retval == -1);
00229 if (connErrno == EINPROGRESS) {
00230 struct NSNetConnectionHandlerInternal *connectHI;
00231 connectHI = calloc(sizeof(*connectHI), 1);
00232 connectHI->ns = ns;
00233 connectHI->nsc = *nsc;
00234 connectHI->fd = fd;
00235 connectHI->dest = dest;
00236 connectHI->udata = udata;
00237 addWriteFd(ns, fd);
00238 addErrFd(ns, fd);
00239 addReadFd(ns, fd);
00240 putInt(ns->connectMap, fd, connectHI);
00241 return 0;
00242 }
00243 rassert(0 && "Unkown connect error");
00244 return 1;
00245 }
00246
00247 #if 0
00248 static char *showFD(sock_t fd, fd_set *readfds, fd_set *writefds, fd_set *errfds) {
00249 static char buf[16];
00250 buf[0] = 0;
00251 if (FD_ISSET(fd, readfds)) strcat(buf, "RE ");
00252 if (FD_ISSET(fd, writefds)) strcat(buf, "WR ");
00253 if (FD_ISSET(fd, errfds)) strcat(buf, "EX ");
00254 if (buf[0] != 0)
00255 buf[strlen(buf)-1] = 0;
00256 return buf;
00257 }
00258 #endif
00259
00260 static void removeReadHandlerInternal(struct NSNet *ns, struct NSNetReadHandlerInternal *readHI)
00261 {
00262 delInt(ns->readerMap, readHI->fd);
00263 free(readHI);
00264 }
00265
00266 static void removeConnectionHandlerInternal(struct NSNet *ns, struct NSNetConnectionHandlerInternal *connectHI)
00267 {
00268 removeFdAll(ns, connectHI->fd);
00269 delInt(ns->connectMap, connectHI->fd);
00270 free(connectHI);
00271 }
00272
00273 void waitForNetEvent(struct NSNet *ns, int timeout)
00274 {
00275 fd_set readfds, writefds, errfds;
00276 sock_t max_fd;
00277 struct timeval tv;
00278 struct NSNetConnectionController *nscc;
00279 struct NSNetBindHandlerInternal *bindHI;
00280 struct NSNetConnectionHandlerInternal *connectHI;
00281 struct NSNetReadHandlerInternal *readerHI;
00282 int retval;
00283 int i;
00284 readfds = ns->readfds;
00285 writefds = ns->writefds;
00286 errfds = ns->errfds;
00287 max_fd = ns->max_fd;
00288 tv.tv_sec = timeout / 1000;
00289 tv.tv_usec = (timeout % 1000) * 1000;
00290 retval = select(max_fd, &readfds, &writefds, &errfds, &tv);
00291 if (retval > 0)
00292 {
00293 int connErrno, connErrnoLen = sizeof(connErrno);
00294 for (i = 0; i < ns->max_fd; i+=1)
00295 {
00296 char buf[1024];
00297 if (FD_ISSET(i, &readfds) && (readerHI = findInt(ns->readerMap, i))) {
00298 int len = read(i, buf, 1024);
00299 if (len > 0)
00300 readerHI->nsrh.bytesRead(readerHI->udata, buf, len);
00301 if (len == 0) {
00302 close(i);
00303 readerHI->nsrh.closed(readerHI->udata);
00304 removeFdAll(ns, i);
00305 removeReadHandlerInternal(ns, readerHI);
00306 }
00307 }
00308 if (FD_ISSET(i, &readfds) && (bindHI = findInt(ns->bindMap, i))) {
00309 int addrlen = sizeof(nscc->peer);
00310 nscc = calloc(sizeof(*nscc), 1);
00311 nscc->ns = ns;
00312 nscc->udata = bindHI->udata;
00313 nscc->fd = accept(i, (struct sockaddr *) &nscc->peer, &addrlen);
00314 setNSnonblocking(ns, nscc->fd);
00315 bindHI->nsb.success(bindHI->udata, nscc);
00316 }
00317 }
00318 for (i = 0; i < ns->max_fd; i+= 1)
00319 {
00320 if ((FD_ISSET(i, &writefds) || FD_ISSET(i, &errfds) || FD_ISSET(i, &readfds)) && (connectHI = findInt(ns->connectMap, i)))
00321 {
00322 if (getsockopt(connectHI->fd, SOL_SOCKET, SO_ERROR, &connErrno, &connErrnoLen) == 0)
00323 {
00324 switch(connErrno)
00325 {
00326 case ECONNREFUSED:
00327 connectHI->nsc.refused(connectHI->udata);
00328 removeConnectionHandlerInternal(ns, connectHI);
00329 break;
00330 case 0:
00331 nscc = calloc(sizeof(*nscc), 1);
00332 nscc->ns = ns;
00333 nscc->peer = connectHI->dest;
00334 nscc->fd = connectHI->fd;
00335 nscc->udata = connectHI->udata;
00336 removeConnectionHandlerInternal(ns, connectHI);
00337 connectHI->nsc.success(connectHI->udata, nscc);
00338 break;
00339 default:
00340 printf("Unhandled connErrno: %d\n", connErrno);
00341 exit(1);
00342 break;
00343 }
00344 return;
00345 }
00346 }
00347 }
00348 }
00349 }
00350
00351 struct NSNet *newNSNet(void)
00352 {
00353 struct NSNet *result;
00354 result = calloc(sizeof(struct NSNet), 1);
00355 FD_ZERO(&result->readfds);
00356 FD_ZERO(&result->writefds);
00357 FD_ZERO(&result->errfds);
00358 result->bindMap = newStringTable();
00359 result->connectMap = newStringTable();
00360 result->readerMap = newStringTable();
00361 return result;
00362 }
00363
00364 void closeNSNet(struct NSNet *ns)
00365 {
00366 freeStringTable(ns->bindMap);
00367 freeStringTable(ns->connectMap);
00368 freeStringTable(ns->readerMap);
00369 free(ns);
00370 }
00371
00372 int closeConnection(struct NSNetConnectionController *nscc)
00373 {
00374 close(nscc->fd);
00375 return 0;
00376 }
00377
00378 int writeNSBytes(struct NSNetConnectionController *nscc, void *buf, int len)
00379 {
00380 int writelen = 0;
00381 if (len > 0)
00382 writelen = write(nscc->fd, buf, len);
00383 return (writelen == len) ? 0 : 1;
00384 }
00385
00386