int socket(int domain, int type, int protocol) { static __thread int recursive; int index, ret; if (recursive) goto real; init_preload(); index = fd_open(); if (index < 0) return index; if (fork_support && (domain == PF_INET || domain == PF_INET6) && (type == SOCK_STREAM) && (!protocol || protocol == IPPROTO_TCP)) { ret = real.socket(domain, type, protocol); if (ret < 0) return ret; fd_store(index, ret, fd_normal, fd_fork); return index; } recursive = 1; ret = rsocket(domain, type, protocol); recursive = 0; if (ret >= 0) { fd_store(index, ret, fd_rsocket, fd_ready); set_rsocket_options(ret); return index; } fd_close(index, &ret); real: return real.socket(domain, type, protocol); }
static int client_connect(void) { struct addrinfo *res; struct pollfd fds; int ret, err; socklen_t len; ret = getaddrinfo(dst_addr, port, NULL, &res); if (ret) { perror("getaddrinfo"); return ret; } rs = rsocket(res->ai_family, res->ai_socktype, res->ai_protocol); if (rs < 0) { perror("rsocket"); ret = rs; goto free; } set_options(rs); /* TODO: bind client to src_addr */ ret = rconnect(rs, res->ai_addr, res->ai_addrlen); if (ret && (errno != EINPROGRESS)) { perror("rconnect"); goto close; } if (ret && (errno == EINPROGRESS)) { fds.fd = rs; fds.events = POLLOUT; ret = do_poll(&fds, poll_timeout); if (ret) goto close; len = sizeof err; ret = rgetsockopt(rs, SOL_SOCKET, SO_ERROR, &err, &len); if (ret) goto close; if (err) { ret = -1; errno = err; perror("async rconnect"); } } close: if (ret) rclose(rs); free: freeaddrinfo(res); return ret; }
RsocketsTransmitter::RsocketsTransmitter(const size_t i, const std::string &address, const size_t port, TransmitterPool &pool) : Transmitter(i, address, port, pool) { cout << "Connecting Rsockets Transmitter to " << serverIP << ", port " << serverPort << endl; int rc; servAddr.sin_family = AF_INET; servAddr.sin_addr.s_addr = inet_addr(serverIP.c_str()); servAddr.sin_port = htons(serverPort); cout << "Thread " << index << ": Connecting to " << endPoint.str() << "..." << endl; sock = rsocket(AF_INET, SOCK_STREAM, 0); assert(sock); rc = rconnect(sock, (struct sockaddr *) &servAddr, sizeof(servAddr)); assert(rc == 0); }
static int server_listen(void) { struct addrinfo hints, *res; int val, ret; memset(&hints, 0, sizeof hints); hints.ai_flags = AI_PASSIVE; ret = getaddrinfo(src_addr, port, &hints, &res); if (ret) { perror("getaddrinfo"); return ret; } lrs = rsocket(res->ai_family, res->ai_socktype, res->ai_protocol); if (lrs < 0) { perror("rsocket"); ret = lrs; goto free; } val = 1; ret = rsetsockopt(lrs, SOL_SOCKET, SO_REUSEADDR, &val, sizeof val); if (ret) { perror("rsetsockopt SO_REUSEADDR"); goto close; } ret = rbind(lrs, res->ai_addr, res->ai_addrlen); if (ret) { perror("rbind"); goto close; } ret = rlisten(lrs, 1); if (ret) perror("rlisten"); close: if (ret) rclose(lrs); free: freeaddrinfo(res); return ret; }
RsocketsReceiver::RsocketsReceiver(const size_t i, const std::string &address, const size_t port, ReceiverPool &pool) : Receiver(i, address, port, pool) { cout << "Starting RDMA Receiver on " << serverIP << ", port " << serverPort << endl; int rc; servAddr.sin_family = AF_INET; servAddr.sin_addr.s_addr = inet_addr(serverIP.c_str()); servAddr.sin_port = htons(port +i); cout << "Thread " << index << ": Binding to " << endPoint.str() << "..." << endl; sock = rsocket(AF_INET, SOCK_STREAM, 0); assert(sock); rc = rbind(sock, (struct sockaddr *) &servAddr, sizeof(servAddr)); assert(rc == 0); rc = rlisten(sock,1); assert(rc == 0); }
/* * We can't fork RDMA connections and pass them from the parent to the child * process. Instead, we need to establish the RDMA connection after calling * fork. To do this, we delay establishing the RDMA connection until we try * to send/receive on the server side. */ static void fork_active(int socket) { struct sockaddr_storage addr; int sfd, dfd, ret; socklen_t len; uint32_t msg; long flags; sfd = fd_getd(socket); flags = real.fcntl(sfd, F_GETFL); real.fcntl(sfd, F_SETFL, 0); ret = real.recv(sfd, &msg, sizeof msg, MSG_PEEK); real.fcntl(sfd, F_SETFL, flags); if ((ret != sizeof msg) || msg) goto err1; len = sizeof addr; ret = real.getpeername(sfd, (struct sockaddr *) &addr, &len); if (ret) goto err1; dfd = rsocket(addr.ss_family, SOCK_STREAM, 0); if (dfd < 0) goto err1; ret = rconnect(dfd, (struct sockaddr *) &addr, len); if (ret) goto err2; set_rsocket_options(dfd); copysockopts(dfd, sfd, &rs, &real); real.shutdown(sfd, SHUT_RDWR); real.close(sfd); fd_store(socket, dfd, fd_rsocket, fd_ready); return; err2: rclose(dfd); err1: fd_store(socket, sfd, fd_normal, fd_ready); }
int main(int argc, char **argv) { char responseBuf[MAXLEN]; int i; int retval; ser_t serport; char EDFPacket[MAXHEADERLEN]; int EDFLen = MAXHEADERLEN; /// buffer for reading from serial port char smallbuf[PROTOWINDOW]; char *hostname = NULL; char *deviceName = NULL; /// DEFAULTHOST; unsigned short portno = 0; /// DEFAULTPORT; struct timeval when; rprintf("ModEEG Driver v. %s-%s\n", VERSION, OSTYPESTR); rinitNetworking(); /// process command line inputs for (i = 1; argv[i]; ++i) { if (argv[i][0] == '-' && argv[i][1] == 'h') { printHelp(); exit(0); } if (argv[i][0] == '-' && argv[i][1] == 'd') { if (argv[i+1] == NULL) { rprintf("Bad devicename option: %s\nExpected device name as next argument.\n", argv[i]); exit(1); } deviceName = argv[i+1]; i += 1; continue; } if (hostname == NULL) { hostname = argv[i]; continue; } if (portno == 0) { portno = atoi(argv[i]); continue; } } if (deviceName == NULL) deviceName = DEFAULTDEVICE; if (portno == 0) portno = DEFAULTPORT; if (hostname == NULL) hostname = DEFAULTHOST; makeREDFConfig(¤t, &modEEGCfg); writeEDFString(¤t, EDFPacket, &EDFLen); sock_fd = rsocket(); if (sock_fd < 0) { perror("socket"); rexit(1); } setblocking(sock_fd); rprintf("Attempting to connect to nsd at %s:%d\n", hostname, portno); retval = rconnectName(sock_fd, hostname, portno); if (retval != 0) { rprintf("connect error\n"); rexit(1); } rprintf("Socket connected.\n"); fflush(stdout); serport = openSerialPort(deviceName,57600); rprintf("Serial port %s opened.\n", deviceName); writeString(sock_fd, "eeg\n", &ob); mGetOK(sock_fd, &ib); writeString(sock_fd, "setheader ", &ob); writeBytes(sock_fd, EDFPacket, EDFLen, &ob); writeString(sock_fd, "\n", &ob); mGetOK(sock_fd, &ib); updateMaxFd(sock_fd); #ifndef __MINGW32__ updateMaxFd(serport); #endif when.tv_usec = (1000000L / modEEGCfg.chan[0].sampleCount); rprintf("Polling at %d Hertz or %d usec\n", modEEGCfg.chan[0].sampleCount, when.tv_usec); for (;;) { int i, readSerBytes; int retval; fd_set toread; when.tv_sec = 0; when.tv_usec = (1000000L / modEEGCfg.chan[0].sampleCount); FD_ZERO(&toread); FD_SET(sock_fd, &toread); #ifndef __MINGW32__ FD_SET(serport, &toread); #endif retval = rselect_timed(max_fd, &toread, NULL, NULL, &when); readSerBytes = readSerial(serport, smallbuf, PROTOWINDOW); if (readSerBytes < 0) { rprintf("Serial error.\n"); } if (readSerBytes > 0) { for (i = 0; i < readSerBytes; ++i) eatCharacter(smallbuf[i]); } if (FD_ISSET(sock_fd, &toread)) { my_read(sock_fd, responseBuf, MAXLEN, &ib); } if (isEOF(sock_fd, &ib)) { rprintf("Server died, exitting.\n"); exit(0); } } return 0; }
void vm_process(VM *vm) { int a, b, opcode; opcode = vm->image[vm->ip]; switch(opcode) { case VM_NOP: break; case VM_LIT: vm->sp++; vm->ip++; TOS = vm->image[vm->ip]; break; case VM_DUP: vm->sp++; vm->data[vm->sp] = NOS; break; case VM_DROP: DROP break; case VM_SWAP: a = TOS; TOS = NOS; NOS = a; break; case VM_PUSH: vm->rsp++; TORS = TOS; DROP break; case VM_POP: vm->sp++; TOS = TORS; vm->rsp--; break; case VM_CALL: vm->ip++; vm->rsp++; TORS = vm->ip; vm->ip = vm->image[vm->ip] - 1; if (vm->ip < 0) vm->ip = IMAGE_SIZE; else { if (vm->image[vm->ip+1] == 0) vm->ip++; if (vm->image[vm->ip+1] == 0) vm->ip++; } break; case VM_JUMP: vm->ip++; vm->ip = vm->image[vm->ip] - 1; if (vm->ip < 0) vm->ip = IMAGE_SIZE; else { if (vm->image[vm->ip+1] == 0) vm->ip++; if (vm->image[vm->ip+1] == 0) vm->ip++; } break; case VM_RETURN: vm->ip = TORS; vm->rsp--; break; case VM_GT_JUMP: vm->ip++; if(NOS > TOS) vm->ip = vm->image[vm->ip] - 1; DROP DROP break; case VM_LT_JUMP: vm->ip++; if(NOS < TOS) vm->ip = vm->image[vm->ip] - 1; DROP DROP break; case VM_NE_JUMP: vm->ip++; if(TOS != NOS) vm->ip = vm->image[vm->ip] - 1; DROP DROP break; case VM_EQ_JUMP: vm->ip++; if(TOS == NOS) vm->ip = vm->image[vm->ip] - 1; DROP DROP break; case VM_FETCH: TOS = vm->image[TOS]; break; case VM_STORE: vm->image[TOS] = NOS; DROP DROP break; case VM_ADD: NOS += TOS; DROP break; case VM_SUB: NOS -= TOS; DROP break; case VM_MUL: NOS *= TOS; DROP break; case VM_DIVMOD: a = TOS; b = NOS; TOS = b / a; NOS = b % a; break; case VM_AND: a = TOS; b = NOS; DROP TOS = a & b; break; case VM_OR: a = TOS; b = NOS; DROP TOS = a | b; break; case VM_XOR: a = TOS; b = NOS; DROP TOS = a ^ b; break; case VM_SHL: a = TOS; b = NOS; DROP TOS = b << a; break; case VM_SHR: a = TOS; b = NOS; DROP TOS = b >>= a; break; case VM_ZERO_EXIT: if (TOS == 0) { DROP vm->ip = TORS; vm->rsp--; } break; case VM_INC: TOS += 1; break; case VM_DEC: TOS -= 1; break; case VM_IN: a = TOS; TOS = vm->ports[a]; vm->ports[a] = 0; break; case VM_OUT: vm->ports[0] = 0; vm->ports[TOS] = NOS; DROP DROP break; case VM_WAIT: if (vm->ports[0] == 1) break; /* Input */ if (vm->ports[0] == 0 && vm->ports[1] == 1) { vm->ports[1] = dev_getch(); vm->ports[0] = 1; } /* Output (character generator) */ if (vm->ports[2] == 1) { dev_putch(TOS); DROP vm->ports[2] = 0; vm->ports[0] = 1; } if (vm->ports[4] != 0) { vm->ports[0] = 1; switch (vm->ports[4]) { case 1: vm_save_image(vm, vm->filename); vm->ports[4] = 0; break; case 2: file_add(vm); vm->ports[4] = 0; break; case -1: vm->ports[4] = file_handle(vm); break; case -2: vm->ports[4] = file_readc(vm); break; case -3: vm->ports[4] = file_writec(vm); break; case -4: vm->ports[4] = file_closehandle(vm); break; case -5: vm->ports[4] = file_getpos(vm); break; case -6: vm->ports[4] = file_seek(vm); break; case -7: vm->ports[4] = file_size(vm); break; default: vm->ports[4] = 0; } } /* Capabilities */ if (vm->ports[5] != 0) { vm->ports[0] = 1; switch(vm->ports[5]) { case -1: vm->ports[5] = IMAGE_SIZE; break; case -2: vm->ports[5] = 0; break; case -3: vm->ports[5] = 0; break; case -4: vm->ports[5] = 0; break; case -5: vm->ports[5] = vm->sp; break; case -6: vm->ports[5] = vm->rsp; break; case -7: vm->ports[5] = 0; break; case -8: vm->ports[5] = time(NULL); break; case -9: vm->ports[5] = 0; vm->ip = IMAGE_SIZE; break; default: vm->ports[5] = 0; } } if (vm->ports[8] != 0) { vm->ports[0] = 1; switch (vm->ports[8]) { case -1: rsocket(vm); vm->ports[8] = 0; break; case -2: rbind(vm); vm->ports[8] = 0; break; case -3: rlisten(vm); vm->ports[8] = 0; break; case -4: raccept(vm); vm->ports[8] = 0; break; case -5: rclose(vm); vm->ports[8] = 0; break; case -6: rsend(vm); vm->ports[8] = 0; break; case -7: rrecv(vm); vm->ports[8] = 0; break; case -8: rconnect(vm); vm->ports[8] = 0; break; default: vm->ports[8] = 0; } vm->ports[8] = 0; } break; default: vm->rsp++; TORS = vm->ip; vm->ip = vm->image[vm->ip] - 1; if (vm->ip < 0) vm->ip = IMAGE_SIZE; else { if (vm->image[vm->ip+1] == 0) vm->ip++; if (vm->image[vm->ip+1] == 0) vm->ip++; } break; } vm->ports[3] = 1; }
/* * The server will start listening for the new connection, then send a * message to the active side when the listen is ready. This does leave * fork unsupported in the following case: the server is nonblocking and * calls select/poll waiting to receive data from the client. */ static void fork_passive(int socket) { struct sockaddr_in6 sin6; sem_t *sem; int lfd, sfd, dfd, ret, param; socklen_t len; uint32_t msg; sfd = fd_getd(socket); len = sizeof sin6; ret = real.getsockname(sfd, (struct sockaddr *) &sin6, &len); if (ret) goto out; sin6.sin6_flowinfo = sin6.sin6_scope_id = 0; memset(&sin6.sin6_addr, 0, sizeof sin6.sin6_addr); sem = sem_open("/rsocket_fork", O_CREAT | O_RDWR, S_IRWXU | S_IRWXG, 1); if (sem == SEM_FAILED) { ret = -1; goto out; } lfd = rsocket(sin6.sin6_family, SOCK_STREAM, 0); if (lfd < 0) { ret = lfd; goto sclose; } param = 1; rsetsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, ¶m, sizeof param); sem_wait(sem); ret = rbind(lfd, (struct sockaddr *) &sin6, sizeof sin6); if (ret) goto lclose; ret = rlisten(lfd, 1); if (ret) goto lclose; msg = 0; len = real.write(sfd, &msg, sizeof msg); if (len != sizeof msg) goto lclose; dfd = raccept(lfd, NULL, NULL); if (dfd < 0) { ret = dfd; goto lclose; } set_rsocket_options(dfd); copysockopts(dfd, sfd, &rs, &real); real.shutdown(sfd, SHUT_RDWR); real.close(sfd); fd_store(socket, dfd, fd_rsocket, fd_ready); lclose: rclose(lfd); sem_post(sem); sclose: sem_close(sem); out: if (ret) fd_store(socket, sfd, fd_normal, fd_ready); }