static int l_message_send(lua_State *L) { mailbox_ref_t *recipient; mailbox_ref_t *sender; message_ref_t *msg_ref;; message_t *msg; message_content_t *content; recipient = luaL_checkudata(L, 1, MAILBOX_REF_TYPE_NAME); sender = mailbox_get(L); //log_debug("Sending message from %p to %p", // (void*)sender, (void*)recipient->mailbox); content = lua_message_pop(L, 1); msg = mailbox_send(sender, recipient, content); if (msg != NULL) { /* Return reference to message */ msg_ref = lua_newuserdata(L, sizeof(message_ref_t)); msg_ref->message = msg; luaL_getmetatable(L, MESSAGE_REF_TYPE_NAME); lua_setmetatable(L, -2); } else { lua_pushboolean(L, 0); lua_message_content_destroy(content); } return 1; }
// the tcpConnection_task_proc handles the connection to one client void tcpConnection_task_proc(void *arg) { tims_msg_head* tcpMsg; connection_t* con = (connection_t*)arg; tims_msg_head replyMsg; int forwardConIndex; int ret, idx; signal(SIGHUP, signal_handler); signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); signal(SIGPIPE, signal_handler); idx = con->index; tims_dbg("con[%02d]: %s: starting TCP/IP connection task\n", idx, inet_ntoa(con->addr.sin_addr)); tcpMsg = malloc(maxMsgSize); if (!tcpMsg) { tims_print("con[%02d] %s error: Can't allocate memory for tcpTimsMsg\n", idx, inet_ntoa(con->addr.sin_addr)); connection_close(con); return; } while (!terminate) { if (con->socket < 0) // invalid socket break; ret = recvTcpTimsMsg(con, tcpMsg); // waiting for new command if (ret < 0) break; if ( !tcpMsg->dest && !tcpMsg->src ) // handle TiMS command (internal) { switch (tcpMsg->type) { case TIMS_MSG_OK: // watchdog lifesign reply con->watchdog = 0; break; case TIMS_MSG_ROUTER_LOGIN: break; case TIMS_MSG_ROUTER_MBX_INIT: mailbox_init(con, tcpMsg, NULL); break; case TIMS_MSG_ROUTER_MBX_DELETE: mailbox_cleanup(con, tcpMsg, NULL); break; case TIMS_MSG_ROUTER_MBX_INIT_WITH_REPLY: mailbox_init(con, tcpMsg, &replyMsg); break; case TIMS_MSG_ROUTER_MBX_DELETE_WITH_REPLY: mailbox_cleanup(con, tcpMsg, &replyMsg); break; case TIMS_MSG_ROUTER_MBX_PURGE: mailbox_purge(con); break; default: tims_print("con[%02d]: %s: received unexpected TiMS " "Message %x -> %x type %i msglen %i\n", idx, inet_ntoa(con->addr.sin_addr), tcpMsg->src, tcpMsg->dest, tcpMsg->type, tcpMsg->msglen); } } else // ( tcpMsg->dest || tcpMsg->src ) { // forward tims message forwardConIndex = mailbox_get(tcpMsg->dest); if (forwardConIndex >= 0) // mbx is available { sndTcpTimsMsg(&conList[forwardConIndex], tcpMsg); } else // mbx is not available { if (tcpMsg->type > 0) { tims_fillhead(&replyMsg, TIMS_MSG_NOT_AVAILABLE, tcpMsg->src, tcpMsg->dest, tcpMsg->priority, tcpMsg->seq_nr, 0, TIMS_HEADLEN); sndTcpTimsMsg(con, &replyMsg); } } } } tims_print("con[%02d]: %s: logout\n", idx, inet_ntoa(con->addr.sin_addr)); mailbox_delete_all(con->index); if (con->socket != -1) connection_close(con); if (tcpMsg) { free(tcpMsg); tcpMsg = NULL; tims_dbgdetail("con[%02d]: %s: free tcp message buffer\n", con->index, inet_ntoa(con->addr.sin_addr)); } con->index = -1; return; }
static void * replay_thread(void *arg) { struct iovec iov[6]; char space[1] = " ", crlf[2] = "\r\n"; struct replay_thread *thr = arg; struct message *msg; enum shmlogtag tag; size_t len; char *ptr; const char *next; int i; int reopen = 1; while ((msg = mailbox_get(&thr->mbox)) != NULL) { tag = msg->tag; len = msg->len; ptr = msg->ptr; thread_log(2, 0, "%s(%s)", VSL_tags[tag], msg->ptr); switch (tag) { case SLT_RxRequest: if (thr->method != NULL) thr->bogus = 1; else thr->method = trimline(thr, ptr); break; case SLT_RxURL: if (thr->url != NULL) thr->bogus = 1; else thr->url = trimline(thr, ptr); break; case SLT_RxProtocol: if (thr->proto != NULL) thr->bogus = 1; else thr->proto = trimline(thr, ptr); break; case SLT_RxHeader: if (thr->nhdr >= sizeof thr->hdr / sizeof *thr->hdr) { thr->bogus = 1; } else { thr->hdr[thr->nhdr++] = trimline(thr, ptr); if (isprefix(ptr, "connection:", &next)) thr->conn = trimline(thr, next); } break; default: break; } freez(msg->ptr); freez(msg); if (tag != SLT_ReqEnd) continue; if (!thr->method || !thr->url || !thr->proto) { thr->bogus = 1; } else if (strcmp(thr->method, "GET") != 0 && strcmp(thr->method, "HEAD") != 0) { thr->bogus = 1; } else if (strcmp(thr->proto, "HTTP/1.0") == 0) { reopen = !(thr->conn && strcasecmp(thr->conn, "keep-alive") == 0); } else if (strcmp(thr->proto, "HTTP/1.1") == 0) { reopen = (thr->conn && strcasecmp(thr->conn, "close") == 0); } else { thr->bogus = 1; } if (thr->bogus) { thread_log(1, 0, "bogus"); goto clear; } if (thr->sock == -1) { for (;;) { thread_log(1, 0, "sleeping before connect..."); usleep(1000 * (thr->fd % 3001)); if ((thr->sock = VSS_connect(addr_info)) >= 0) break; thread_log(0, errno, "connect failed"); } } thread_log(1, 0, "%s %s %s", thr->method, thr->url, thr->proto); iov[0].iov_base = thr->method; iov[0].iov_len = strlen(thr->method); iov[2].iov_base = thr->url; iov[2].iov_len = strlen(thr->url); iov[4].iov_base = thr->proto; iov[4].iov_len = strlen(thr->proto); iov[1].iov_base = iov[3].iov_base = space; iov[1].iov_len = iov[3].iov_len = 1; iov[5].iov_base = crlf; iov[5].iov_len = 2; if (writev(thr->sock, iov, 6) == -1) { thread_log(0, errno, "writev()"); goto close; } for (i = 0; i < thr->nhdr; ++i) { thread_log(2, 0, "%d %s", i, thr->hdr[i]); iov[0].iov_base = thr->hdr[i]; iov[0].iov_len = strlen(thr->hdr[i]); iov[1].iov_base = crlf; iov[1].iov_len = 2; if (writev(thr->sock, iov, 2) == -1) { thread_log(0, errno, "writev()"); goto close; } } if (write(thr->sock, crlf, 2) == -1) { thread_log(0, errno, "writev()"); goto close; } if (receive_response(thr) || reopen) { close: thread_log(1, 0, "close"); assert(thr->sock != -1); close(thr->sock); thr->sock = -1; } sleep(1); clear: /* clean up */ thread_clear(thr); } /* leftovers */ thread_clear(thr); return (0); }
static int l_message_receive(lua_State *L) { mailbox_ref_t *mailbox; mailbox = mailbox_get(L); return 0; }