int getsockname(int sockfd, struct sockaddr* address, socklen_t* address_len) { uint32_t id ; if (monapi_name_whereis("/servers/net", id) != M_OK) { return EBADF; } char buf[sizeof(socklen_t)]; memcpy(buf, address_len, sizeof(socklen_t)); if (Message::send(id, MSG_NET_GET_SOCKNAME, sockfd, 0, 0, buf) != M_OK) { return EBADF; } BufferReceiver* receiver = Message::receiveBuffer(id); *address_len = receiver->bufferSize(); memcpy(address, receiver->buffer(), *address_len); delete receiver; MessageInfo src; MessageInfo dst; src.from = id; src.header = MSG_OK; src.arg1 = MSG_NET_GET_SOCKNAME; if (Message::receive(&dst, &src, Message::equalsFromHeaderArg1) != M_OK) { return EBADF; } errno = dst.arg3; return dst.arg2; }
int accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen) { uint32_t id ; if (monapi_name_whereis("/servers/net", id) != M_OK) { return EBADF; } MessageInfo msg; if (Message::sendReceive(&msg, id, MSG_NET_SOCKET_ACCEPT, sockfd) != M_OK) { return EBADF; } uintptr_t waitId = msg.arg2; BufferReceiver* receiver = Message::receiveBuffer(waitId); *addrlen = receiver->bufferSize(); if (receiver->bufferSize() != 0) { memcpy(addr, receiver->buffer(), (*addrlen) > sizeof(sockaddr) ? sizeof(sockaddr) : *addrlen); } delete receiver; MessageInfo src; MessageInfo dst; src.from = waitId; src.header = MSG_OK; src.arg1 = MSG_NET_SOCKET_ACCEPT; if (Message::receive(&dst, &src, Message::equalsFromHeaderArg1) != M_OK) { return EBADF; } errno = dst.arg3; return dst.arg2; }
int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen) { uint32_t id ; if (monapi_name_whereis("/servers/net", id) != M_OK) { return EBADF; } char buf[sizeof(socklen_t)]; memcpy(buf, optlen, sizeof(socklen_t)); if (Message::send(id, MSG_NET_SOCKET_GET_OPTION, sockfd, level, optname, buf) != M_OK) { return EBADF; } BufferReceiver* receiver = Message::receiveBuffer(id); *optlen = receiver->bufferSize(); memcpy(optval, receiver->buffer(), *optlen); delete receiver; MessageInfo src; MessageInfo dst; src.from = id; src.header = MSG_OK; src.arg1 = MSG_NET_SOCKET_GET_OPTION; if (Message::receive(&dst, &src, Message::equalsFromHeaderArg1) != M_OK) { return EBADF; } errno = dst.arg3; return dst.arg2; }
int recv(int sockfd, void* buf, size_t len, int flags) { uint32_t id ; if (monapi_name_whereis("/servers/net", id) != M_OK) { return EBADF; } if (Message::send(id, MSG_NET_SOCKET_RECV, sockfd, len, flags) != M_OK) { return EBADF; } BufferReceiver* receiver = Message::receiveBuffer(id); if (receiver->bufferSize() > 0) { memcpy(buf, receiver->buffer(), receiver->bufferSize()); } MessageInfo src; MessageInfo dst; src.from = id; src.header = MSG_OK; src.arg1 = MSG_NET_SOCKET_RECV; if (Message::receive(&dst, &src, Message::equalsFromHeaderArg1) != M_OK) { return EBADF; } errno = dst.arg3; return dst.arg2; }
int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { // construct addrinfo to struct uintptr_t nodeLen = node == NULL ? 0 : strlen(node) + 1; uintptr_t serviceLen = service == NULL ? 0 : strlen(service) + 1; uintptr_t structSize = sizeof(GetaddrinfoPacket) + nodeLen + serviceLen; uint8_t* p = new uint8_t[structSize]; GetaddrinfoPacket* pack = (GetaddrinfoPacket*)p; pack->nodeLen = nodeLen; pack->hints = *hints; if (node != NULL) { strcpy(pack->data, node); } if (service != NULL) { strcpy(pack->data + nodeLen, service); } uint32_t id ; if (monapi_name_whereis("/servers/net", id) != M_OK) { return M_NAME_NOT_FOUND; } if (Message::send(id, MSG_NET_GET_ADDR_INFO) != M_OK) { return EBADF; } if (Message::sendBuffer(id, p, structSize) != M_OK) { return EBADF; } BufferReceiver* receiver = Message::receiveBuffer(id); if (receiver->bufferSize() != 0) { struct addrinfo* ainfo = new struct addrinfo; memcpy(ainfo, receiver->buffer(), sizeof(struct addrinfo)); ainfo->ai_addr = (struct sockaddr*)(new uint8_t[ainfo->ai_addrlen]); memcpy(ainfo->ai_addr, receiver->buffer() + sizeof(struct addrinfo), ainfo->ai_addrlen); MONA_ASSERT(receiver->bufferSize() == (sizeof(struct addrinfo) + ainfo->ai_addrlen)); *res = ainfo; } delete receiver; MessageInfo src; MessageInfo dst; src.from = id; src.header = MSG_OK; src.arg1 = MSG_NET_GET_ADDR_INFO; if (Message::receive(&dst, &src, Message::equalsFromHeaderArg1) != M_OK) { return EBADF; } return dst.arg2; }
// caller should delete BufferReceiver. BufferReceiver* Message::receiveBuffer(uintptr_t tid) { BufferReceiver* receiver; for (;;) { MessageInfo expectedMsg; expectedMsg.from = tid; MessageInfo msg; if (Message::receive(&msg, &expectedMsg, isSendBufferPacket) != M_OK) { continue; } if (msg.header == Message::MSG_SEND_BUFFER_START) { uintptr_t bufferSize = msg.arg1; receiver = new BufferReceiver(bufferSize); receiver->receive(msg.str, MESSAGE_INFO_MAX_STR_LENGTH); } else if (msg.header == Message::MSG_SEND_BUFFER_PACKET) { ASSERT(receiver != NULL); receiver->receive(msg.str, MESSAGE_INFO_MAX_STR_LENGTH); } if (receiver->isDone()) { return receiver; } } }
static void __fastcall messageLoop(void* arg) { if (monapi_notify_server_start("MONITOR.BIN") != M_OK) { MONAPI_WARN("net server can't notify to MONITOR"); exit(-1); } for (;;) { MessageInfo msg; if (Message::receive(&msg) != M_OK) { continue; } switch (msg.header) { case MSG_NET_SOCKET_CONN: { int sockfd = msg.arg1; socklen_t namelen = msg.arg2; BufferReceiver* receiver = Message::receiveBuffer(msg.from); int ret = connect(sockfd, (struct sockaddr*)receiver->buffer(), namelen); delete receiver; if (Message::reply(&msg, ret, errno) != M_OK) { MONAPI_WARN("failed to reply %s", __func__); } break; } case MSG_NET_SOCKET_BIND: { int sockfd = msg.arg1; socklen_t addrlen = msg.arg2; BufferReceiver* receiver = Message::receiveBuffer(msg.from); int ret = bind(sockfd, (struct sockaddr*)receiver->buffer(), addrlen); delete receiver; if (Message::reply(&msg, ret, errno) != M_OK) { MONAPI_WARN("failed to reply %s", __func__); } break; } case MSG_NET_SOCKET_SOCK: { int domain = msg.arg1; int type = msg.arg2; int protocol = msg.arg3; int ret = socket(domain, type, protocol); if (Message::reply(&msg, ret, errno) != M_OK) { MONAPI_WARN("failed to reply %s", __func__); } break; } case MSG_NET_SOCKET_LISTEN: { int sockfd = msg.arg1; int backlog = msg.arg2; int ret = listen(sockfd, backlog); if (Message::reply(&msg, ret, errno) != M_OK) { MONAPI_WARN("failed to reply %s", __func__); } break; } case MSG_NET_SOCKET_SHUTDOWN: { int sockfd = msg.arg1; int how = msg.arg2; int ret = shutdown(sockfd, how); if (Message::reply(&msg, ret, errno) != M_OK) { MONAPI_WARN("failed to reply %s", __func__); } break; } case MSG_NET_SOCKET_CLOSE: { int sockfd = msg.arg1; int ret = close(sockfd); if (Message::reply(&msg, ret) != M_OK) { MONAPI_WARN("failed to reply %s", __func__); } break; } case MSG_NET_SOCKET_SEND: { int sockfd = msg.arg1; size_t len = msg.arg2; int flags = msg.arg3; BufferReceiver* receiver = Message::receiveBuffer(msg.from); int ret = send(sockfd, receiver->buffer(), len, flags); delete receiver; if (Message::reply(&msg, ret, errno) != M_OK) { MONAPI_WARN("failed to reply %s", __func__); } break; } case MSG_NET_SOCKET_SET_OPTION: { int sockfd = msg.arg1; int level = msg.arg2; int optname = msg.arg3; BufferReceiver* receiver = Message::receiveBuffer(msg.from); void* optval = (void*)receiver->buffer(); int optlen = receiver->bufferSize(); int ret = setsockopt(sockfd, level, optname, optval, optlen); delete receiver; if (Message::reply(&msg, ret, errno) != M_OK) { MONAPI_WARN("failed to reply %s", __func__); } break; } case MSG_NET_SOCKET_ACCEPT: { int sockfd = msg.arg1; struct sockaddr_in waddr; socklen_t writer_len; int s = accept(sockfd, (struct sockaddr*)&waddr, &writer_len); if (Message::sendBuffer(msg.from, &waddr, writer_len) != M_OK) { MONAPI_WARN("failed to reply %s", __func__); } if (Message::reply(&msg, s, errno) != M_OK) { MONAPI_WARN("failed to reply %s", __func__); } break; } case MSG_NET_SOCKET_GET_OPTION: { int sockfd = msg.arg1; int level = msg.arg2; int optname = msg.arg3; socklen_t optlen = *((socklen_t*)&msg.str); uint8_t* buf = new uint8_t[optlen]; int ret = getsockopt(sockfd, level, optname, buf, &optlen); if (Message::sendBuffer(msg.from, buf, optlen) != M_OK) { MONAPI_WARN("failed to reply %s", __func__); } delete[] buf; if (Message::reply(&msg, ret, errno) != M_OK) { MONAPI_WARN("failed to reply %s", __func__); } break; } case MSG_NET_SOCKET_RECV: { static uint8_t* buffer = NULL; static uintptr_t bufferSize = 127; if (NULL == buffer) { buffer = new uint8_t[bufferSize]; } int sockfd = msg.arg1; size_t len = msg.arg2; int flags = msg.arg3; if (len > bufferSize) { if (buffer != NULL) { delete[] buffer; } bufferSize = len; buffer = new uint8_t[bufferSize]; } int ret = recv(sockfd, buffer, len, flags); if (Message::sendBuffer(msg.from, buffer, ret > 0 ? ret : 0) != M_OK) { MONAPI_WARN("failed to reply %s", __func__); } if (Message::reply(&msg, ret, errno) != M_OK) { MONAPI_WARN("failed to reply %s", __func__); } break; } case MSG_NET_GET_ADDR_INFO: { BufferReceiver* receiver = Message::receiveBuffer(msg.from); if (receiver->bufferSize() <= sizeof(GetaddrinfoPacket)) { MONAPI_WARN("getaddrinfoPacket is too small"); break; } GetaddrinfoPacket* packet = (GetaddrinfoPacket*)receiver->buffer(); struct addrinfo *res; int ret = getaddrinfo(packet->data, packet->data + packet->nodeLen, &packet->hints, &res); delete receiver; if (ret == 0) { int packetLength = res->ai_addrlen + sizeof(struct addrinfo); uint8_t* packet = new uint8_t[packetLength]; memcpy(packet, res, sizeof(struct addrinfo)); memcpy(packet + sizeof(struct addrinfo), res->ai_addr, res->ai_addrlen); if (Message::sendBuffer(msg.from, packet, packetLength) != M_OK) { MONAPI_WARN("failed to send buffer %s:%d", __func__, __LINE__); } delete[] packet; } else { if (Message::sendBuffer(msg.from, NULL, 0) != M_OK) { MONAPI_WARN("failed to send buffer %s:%d", __func__, __LINE__); } } freeaddrinfo(res); if (Message::reply(&msg, ret, errno) != M_OK) { MONAPI_WARN("failed to reply %s:%d", __func__, __LINE__); } break; } case MSG_NET_SELECT: { int nfds = msg.arg1; bool haveReadFds = msg.str[0]; bool haveWriteFds = msg.str[1]; bool haveExceptFds = msg.str[2]; bool haveTimeout = msg.str[3]; fd_set* readfds = haveReadFds ? (fd_set*)&msg.str[4] : NULL; fd_set* writefds = haveWriteFds ? (fd_set*)&msg.str[4 + sizeof(fd_set)] : NULL; fd_set* exceptfds = haveExceptFds ? (fd_set*)&msg.str[4 + sizeof(fd_set) * 2] : NULL; struct timeval* timeout = haveTimeout ? (struct timeval*)&msg.str[4 + sizeof(fd_set) * 3] : NULL; int ret = select(nfds, readfds, writefds, exceptfds, timeout); if (haveReadFds) { *((fd_set*)msg.str) = *readfds; } if (haveWriteFds) { *((fd_set*)(&msg.str[sizeof(fd_set)])) = *writefds; } if (haveExceptFds) { *((fd_set*)(&msg.str[sizeof(fd_set) * 2])) = *exceptfds; } if (haveTimeout) { *((struct timeval*)(&msg.str[sizeof(fd_set) * 3])) = *timeout; } if (Message::reply(&msg, ret, errno) != M_OK) { MONAPI_WARN("failed to reply %s", __func__); } break; } case MSG_NET_SOCKET_CONTROL: { int sockfd = msg.arg1; long cmd = msg.arg2; bool haveArgp = msg.arg3; uint32_t* argp = NULL; if (haveArgp) { argp = (uint32_t*)msg.str; } int ret = ioctlsocket(sockfd, cmd, argp); if (Message::reply(&msg, ret, errno) != M_OK) { MONAPI_WARN("failed to reply %s", __func__); } break; } } } }