Exemple #1
0
static int process_new_notification(pblock *param,
                                    Session *sn,
                                    Request *rq,
                                    void* agent_config)
{
    handle_notification(sn, rq, agent_config);

    /* Use the protocol_status function to set the status of the
     * response before calling protocol_start_response.
     */
    protocol_status(sn, rq, PROTOCOL_OK, NULL);

    /* Although we would expect the ObjectType stage to
     * set the content-type, set it here just to be
     * completely sure that it gets set to text/html.
     */
    param_free(pblock_remove("content-type", rq->srvhdrs));
    pblock_nvinsert("content-type", "text/html", rq->srvhdrs);

    pblock_nvinsert("content-length", "2", rq->srvhdrs);

    /* Send the headers to the client*/
    protocol_start_response(sn, rq);

    /* Write the output using net_write*/
    if (IO_ERROR == net_write(sn->csd, "OK", 2)) {
        return REQ_EXIT;
    }
    return REQ_PROCEED;
}
Exemple #2
0
/* This is the C function which allows to cause a variable change notification in the Lua VM.
 * Its works differently, depending on whether it's called from the thread in which the Lua
 * VM runs:
 *
 * * in all cases, it stores the notification description in `notify_buffer`.
 * * if it runs in the Lua VM thread, it calls the Lua handler directly;
 * * if called from another thread, it sends a Lua signal, which will trigger
 *   the notification handler, and waits until the handling is completed; completion
 *   is signaled by the release of a dedicated `notify_buffer->handled` mutex.
 */
static swi_status_t trigger_notification(void *ctx, int nvars, ExtVars_id_t* vars, void** values, ExtVars_type_t* types) {

    ExtVars_Mod_t *mod = (ExtVars_Mod_t *)ctx;
    /* make sure that only one notification is in progress. */
    pthread_mutex_lock(&notify_buffer.inprogress);

    notify_buffer.handler_name = mod->name;
    notify_buffer.nvars        = nvars;
    notify_buffer.vars         = vars;
    notify_buffer.values       = values;
    notify_buffer.types        = types;

    if(pthread_self() == notify_buffer.lua_thread) { /* Direct nested call */
        handle_notification(notify_buffer.L);
    } else { /* Triggered through a pre-subscribed Lua signal */
        LUASIGNAL_SignalT( notify_buffer.luasigctx, NOTIFY_SIGEMITTER, NOTIFY_SIGEVENT, NULL);
    }

    /* If this function runs in the lua thread, the `handled` semaphore has already been released by the
     * Lua notification handler.
     *
     * If this thread is not the lua thread, the lua signal sent above will eventually cause the lua
     * handler to run, which will eventually release the `handled` sem.
     * Until this happens, the current thread pauses, and the notification ctx won't be altered. */
    sem_wait(&notify_buffer.handled);

    pthread_mutex_unlock(&notify_buffer.inprogress);

    return SWI_STATUS_OK;
}
static int
receive_cb(struct socket *sock, union sctp_sockstore addr, void *data,
           size_t datalen, struct sctp_rcvinfo rcv, int flags, void *ulp_info)
{
	if (data) {
		if (flags & MSG_NOTIFICATION) {
			handle_notification((union sctp_notification *)data, datalen);
		} else {
			printf("Msg of length %d received via %p:%u on stream %d with SSN %u and TSN %u, PPID %d, context %u.\n",
			       (int)datalen,
			       addr.sconn.sconn_addr,
			       ntohs(addr.sconn.sconn_port),
			       rcv.rcv_sid,
			       rcv.rcv_ssn,
			       rcv.rcv_tsn,
			       ntohl(rcv.rcv_ppid),
			       rcv.rcv_context);
		}
		free(data);
	} else {
		usrsctp_deregister_address(ulp_info);
		usrsctp_close(sock);
	}
	return 1;
}
	bool ouroboros_server::set(const std::string& aGroup, const std::string& aField, const var_field& aFieldData)
	{
		var_field *result = mStore.get(normalize_group(aGroup), aField);
		if (!result)
		{
			return false;
		}
		result->setJSON(aFieldData.getJSON());

		handle_notification(aGroup, aField);
		return true;
	}
	void ouroboros_server::handle_name_rest(const rest_request& aRequest)
	{
		//get reference to named thing
		var_field *named = mStore.get(normalize_group(aRequest.getGroups()), aRequest.getFields());

		std::string sjson;
		mg_connection *conn = aRequest.getConnection();
		if (named)
		{
			switch (aRequest.getHttpRequestType())
			{
				case PUT:
				{
					std::string data(conn->content, conn->content_len);
					JSON json(data);

					if (named->setJSON(json))
					{
						handle_notification(aRequest.getGroups(), aRequest.getFields());
						sjson = detail::good_JSON();
					}
					else
					{
						sjson = detail::bad_JSON(conn);
					}
				}
					break;

				case GET:
					//Send JSON describing named item
					sjson = named->getJSON();
					break;

				default:
					sjson = detail::bad_JSON(conn);
			}
		}
		else
		{
			sjson = detail::bad_JSON(conn);
		}

		mg_send_data(conn, sjson.c_str(), sjson.length());
	}
Exemple #6
0
static int
receive_cb(struct socket *sock, union sctp_sockstore addr, void *data,
           size_t datalen, struct sctp_rcvinfo rcv, int flags, void *ulp_info)
{
	struct peer_connection *pc;

	pc = (struct peer_connection *)ulp_info;

	if (data) {
		lock_peer_connection(pc);
		if (flags & MSG_NOTIFICATION) {
			handle_notification(pc, (union sctp_notification *)data, datalen);
		} else {
			handle_message(pc, data, datalen, ntohl(rcv.rcv_ppid), rcv.rcv_sid);
		}
		unlock_peer_connection(pc);
	}
	return (1);
}
Exemple #7
0
int
sctpReadInput(int fd, distributor *o,sctpAdaptorMod *r)
{
  /* receive some number of datagrams and act on them. */
  struct sctp_sndrcvinfo *s_info;
  socklen_t from_len;
  int sz,i,disped,ll;
  messageEnvolope msgout;
  struct msghdr msg;
  struct iovec iov[2];
  unsigned char from[200];
  char readBuffer[65535];
  char controlVector[65535];

  disped = i = 0;

  from_len = sizeof(from);
  if((fd == mainFd) && 
     (r->model & SCTP_TCP_TYPE) &&
     (r->model & SCTP_TCP_IS_LISTENING)){
    /* are we using TCP model here, maybe */
    int newfd;
    newfd = accept(fd, (struct sockaddr *)from, &from_len);
    if(newfd != -1){
      printf("New fd accepted fd=%d from:",newfd);
      SCTPPrintAnAddress((struct sockaddr *)from);
      dist_addFd(o,newfd,sctpFdInput,POLLIN,(void *)r);
      printf("Added new fd, now returning\n");
      return(0);
    }else{
      printf("Accept failed err:%d\n",errno);
      printf("Fall through and let read fail (hopefully :>)\n");
    }
  }
  s_info = NULL;
  iov[0].iov_base = readBuffer;
  ll = iov[0].iov_len = sizeof(readBuffer);
  iov[1].iov_base = NULL;
  iov[1].iov_len = 0;
  msg.msg_name = (caddr_t)from;
  msg.msg_namelen = from_len;
  msg.msg_iov = iov;
  msg.msg_iovlen = 1;
  msg.msg_control = (caddr_t)controlVector;
  msg.msg_flags = 0;
  msg.msg_controllen = sizeof(controlVector);
  errno = 0;
  sz = sctp_recvmsg (fd, 
		     readBuffer, 
		     (size_t)ll,
		     (struct sockaddr *)&from,
		     &from_len,
		     &o_info,
		     &msg.msg_flags);
  s_info = &o_info;

  if(sz <= 0){
    if (sz == 0) {
      if (fd != mainFd) {
        printf("Connected fd:%d  gets 0/0 remove from dist\n",fd);
        dist_deleteFd(o,fd);
        return(0);
      } else {
	/* our mainFd went EOF on us... probably a 1-to-1 socket */
        printf("Main fd:%d got EOF... please quit and restart now...\n",fd);
	close(fd);
        dist_deleteFd(o,fd);
	return(0);
      }
    }
    if((errno != ENOBUFS) && (errno != EAGAIN))
      printf("Read returns %d errno:%d control len is %d msgflg:0x%x\n",
	     sz,errno,
	     msg.msg_controllen,msg.msg_flags);
    if(errno == EBADF){
      /* FD went bad */
      if(fd != mainFd){
	close(fd);
	printf("FD:%d now closes\n",fd);
      }
      printf("Bad FD removed\n");
      dist_deleteFd(o,fd);
    }
    if(msg.msg_flags & MSG_EOR){
      if(dataout != NULL)
	goto deliverIt;
    }
    return(0);
  }
  big_o = o;
  if (msg.msg_flags & MSG_NOTIFICATION) {
    handle_notification(fd,readBuffer);
    return(0);
  }

  msgout.takeOk = 0;
  msgout.protocolId = 0;
  lastStream = msgout.streamNo = 0;
  lastStreamSeq = msgout.streamSeq = 0;

  if((dataout == NULL) && (msg.msg_flags & MSG_EOR)){
    if(o_info.sinfo_assoc_id){
      msgout.protocolId = o_info.sinfo_ppid;
      lastStream = msgout.streamNo = o_info.sinfo_stream;
      lastStreamSeq = msgout.streamSeq = o_info.sinfo_ssn;
    }else{
      printf("Gak! no info set with full msg\n");
    }
    msgout.takeOk = 0;
    msgout.totSize = sz;
    msgout.totData = readBuffer;
    msgout.siz = sz;
    msgout.data = readBuffer;
    msgout.from = &from;
    msgout.type = PROTOCOL_Sctp;
    msgout.to = NULL;
    msgout.origFrom = NULL;
    msgout.origType =  PROTOCOL_Unknown;
    msgout.sender = (void *)&mainFd;
    dist_sendmessage(o,&msgout);
  }else{
    char *newout;
    if(sctp_verbose) {
	    printf("PARTIAL DELIVERY OF %d bytes (dtsize:%d)\n",
		   sz,dtsize);
    }
    newout = calloc(1,(sz + dtsize));
    if(newout == NULL){
      printf("Gak! I am out of memory? .. drop a message\n");
      if(dataout)
	free(dataout);
      dataout = NULL;
      dtsize = 0;
      return(0);
    }
    if(dataout){
      memcpy(newout,dataout,dtsize);
    }
    memcpy(&newout[dtsize],readBuffer,sz);
    dtsize += sz;
    if(dataout){
      free(dataout);
    }
    dataout = newout;
  deliverIt:
    if(msg.msg_flags & MSG_EOR){
      /* Ok we can deliver this guy now */
      if(o_info.sinfo_assoc_id){
	msgout.protocolId = o_info.sinfo_ppid;
	lastStream = msgout.streamNo = o_info.sinfo_stream;
	lastStreamSeq = msgout.streamSeq = o_info.sinfo_ssn;
      }else{
	printf("Gak! no info set with msg delivery?\n");
      }
      msgout.takeOk = 1;
      msgout.totSize = dtsize;
      msgout.totData = dataout;
      msgout.siz = dtsize;
      msgout.data = dataout;
      msgout.from = &from;
      msgout.type = PROTOCOL_Sctp;
      msgout.to = NULL;
      msgout.origFrom = NULL;
      msgout.origType =  PROTOCOL_Unknown;
      msgout.sender = (void *)&mainFd;
      dist_sendmessage(o,&msgout);
      dataout = NULL;
      dtsize = 0;
    }
  }
  return(0);
}