Beispiel #1
0
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);
}
Beispiel #4
0
static int l_message_receive(lua_State *L) {
	mailbox_ref_t *mailbox;
	mailbox = mailbox_get(L);

	return 0;
}