Пример #1
0
/* Write some data to the socket.  If the write is not COMPLETED within
 * timeout_msecs , NSE_STATUS_TIMEOUT will be returned.  If you are supplying
 * NUL-terminated data, you can optionally pass -1 for datalen and nsock_write
 * will figure out the length itself */
nsock_event_id nsock_write(nsock_pool ms_pool, nsock_iod ms_iod,
          nsock_ev_handler handler, int timeout_msecs, void *userdata, const char *data, int datalen) {
  mspool *nsp = (mspool *)ms_pool;
  msiod *nsi = (msiod *)ms_iod;
  msevent *nse;
  char displaystr[256];

  nse = msevent_new(nsp, NSE_TYPE_WRITE, nsi, timeout_msecs, handler, userdata);
  assert(nse);

  nse->writeinfo.dest.ss_family = AF_UNSPEC;

  if (datalen < 0)
    datalen = (int)strlen(data);

    if (nsp->loglevel == NSOCK_LOG_DBG_ALL && datalen < 80) {
      memcpy(displaystr, ": ", 2);
      memcpy(displaystr + 2, data, datalen);
      displaystr[2 + datalen] = '\0';
      replacenonprintable(displaystr + 2, datalen, '.');
    } else {
      displaystr[0] = '\0';
    }

    nsock_log_debug(nsp, "Write request for %d bytes to IOD #%li EID %li [%s]%s",
                    datalen, nsi->id, nse->id, get_peeraddr_string(nsi), displaystr);

  fs_cat(&nse->iobuf, data, datalen);

  nsp_add_event(nsp, nse);

  return nse->id;
}
Пример #2
0
nsock_event_id nsock_sendto(nsock_pool ms_pool, nsock_iod ms_iod, nsock_ev_handler handler, int timeout_msecs,
                            void *userdata, struct sockaddr *saddr, size_t sslen, unsigned short port, const char *data, int datalen) {
  mspool *nsp = (mspool *)ms_pool;
  msiod *nsi = (msiod *)ms_iod;
  msevent *nse;
  char displaystr[256];
  struct sockaddr_in *sin = (struct sockaddr_in *)saddr;
#if HAVE_IPV6
  struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)saddr;
#endif

  nse = msevent_new(nsp, NSE_TYPE_WRITE, nsi, timeout_msecs, handler, userdata);
  assert(nse);

  if (saddr->sa_family == AF_INET) {
    sin->sin_port = htons(port);
#if HAVE_SYS_UN_H
  } else if (saddr->sa_family == AF_INET6) {
#else
  } else {
#endif
    assert(saddr->sa_family == AF_INET6);
#if HAVE_IPV6
    sin6->sin6_port = htons(port);
#else
    fatal("IPv6 address passed to %s call, but nsock was not compiled w/IPv6 support", __func__);
#endif
  }

  assert(sslen <= sizeof(nse->writeinfo.dest));
  memcpy(&nse->writeinfo.dest, saddr, sslen);
  nse->writeinfo.destlen = sslen;

  assert(sslen <= sizeof(nse->iod->peer));
  memcpy(&nse->iod->peer, saddr, sslen);
  nse->iod->peerlen = sslen;

  if (datalen < 0)
    datalen = (int) strlen(data);

  if (nsp->loglevel == NSOCK_LOG_DBG_ALL && datalen < 80) {
    memcpy(displaystr, ": ", 2);
    memcpy(displaystr + 2, data, datalen);
    displaystr[2 + datalen] = '\0';
    replacenonprintable(displaystr + 2, datalen, '.');
  } else {
    displaystr[0] = '\0';
  }
  nsock_log_debug(nsp, "Sendto request for %d bytes to IOD #%li EID %li [%s]%s",
                  datalen, nsi->id, nse->id, get_peeraddr_string(nse->iod), displaystr);

  fs_cat(&nse->iobuf, data, datalen);

  nsp_add_event(nsp, nse);

  return nse->id;
}
Пример #3
0
/* The simplest read function -- returns NSE_STATUS_SUCCESS when it
 * reads anything, otherwise it returns timeout, eof, or error as appropriate */
nsock_event_id nsock_read(nsock_pool nsp, nsock_iod ms_iod,
                          nsock_ev_handler handler, int timeout_msecs,
                          void *userdata) {
  struct niod *nsi = (struct niod *)ms_iod;
  struct npool *ms = (struct npool *)nsp;
  struct nevent *nse;

  nse = event_new(ms, NSE_TYPE_READ, nsi, timeout_msecs, handler, userdata);
  assert(nse);

  nsock_log_info(ms, "Read request from IOD #%li [%s] (timeout: %dms) EID %li",
                 nsi->id, get_peeraddr_string(nsi), timeout_msecs, nse->id);

  nse->readinfo.read_type = NSOCK_READ;

  nsp_add_event(ms, nse);

  return nse->id;
}
Пример #4
0
/* Read up to nlines lines (terminated with \n, which of course includes \r\n),
 * or until EOF, or until the timeout, whichever comes first.  Note that
 * NSE_STATUS_SUCCESS will be returned in the case of EOF or timeout if at least
 * 1 char has been read.  Also note that you may get more than 'nlines' back --
 * we just stop once "at least" 'nlines' is read */
nsock_event_id nsock_readlines(nsock_pool nsp, nsock_iod ms_iod,
                               nsock_ev_handler handler, int timeout_msecs,
                               void *userdata, int nlines) {
  msiod *nsi = (msiod *)ms_iod;
  mspool *ms = (mspool *)nsp;
  msevent *nse;

  nse = msevent_new(ms, NSE_TYPE_READ, nsi, timeout_msecs, handler, userdata);
  assert(nse);

  nsock_log_info(ms, "Read request for %d lines from IOD #%li [%s] EID %li",
                 nlines, nsi->id, get_peeraddr_string(nsi), nse->id);

  nse->readinfo.read_type = NSOCK_READLINES;
  nse->readinfo.num = nlines;

  nsp_add_event(ms, nse);

  return nse->id;
}
Пример #5
0
/* An event has been completed and the handler is about to be called. This
 * function writes out tracing data about the event if necessary */
void nsock_trace_handler_callback(struct npool *ms, struct nevent *nse) {
  struct niod *nsi;
  char *str;
  int strlength = 0;
  char displaystr[256];
  char errstr[256];

  if (NsockLogLevel > NSOCK_LOG_INFO)
    return;

  nsi = nse->iod;

  if (nse->status == NSE_STATUS_ERROR)
    Snprintf(errstr, sizeof(errstr), "[%s (%d)] ", socket_strerror(nse->errnum),
             nse->errnum);
  else
    errstr[0] = '\0';

  /* Some types have special tracing treatment */
  switch (nse->type) {
    case NSE_TYPE_CONNECT:
    case NSE_TYPE_CONNECT_SSL:
      nsock_log_info("Callback: %s %s %sfor EID %li [%s]",
                     nse_type2str(nse->type), nse_status2str(nse->status),
                     errstr, nse->id, get_peeraddr_string(nsi));
      break;

    case NSE_TYPE_READ:
      if (nse->status != NSE_STATUS_SUCCESS) {
        nsock_log_info("Callback: %s %s %sfor EID %li [%s]",
                       nse_type2str(nse->type), nse_status2str(nse->status),
                       errstr, nse->id, get_peeraddr_string(nsi));
      } else {
        str = nse_readbuf(nse, &strlength);
        if (strlength < 80) {
          memcpy(displaystr, ": ", 2);
          memcpy(displaystr + 2, str, strlength);
          displaystr[2 + strlength] = '\0';
          replacenonprintable(displaystr + 2, strlength, '.');
        } else {
          displaystr[0] = '\0';
        }
        nsock_log_info("Callback: %s %s for EID %li [%s] %s(%d bytes)%s",
                       nse_type2str(nse->type), nse_status2str(nse->status),
                       nse->id,
                       get_peeraddr_string(nsi),
                       nse_eof(nse) ? "[EOF]" : "", strlength, displaystr);
      }
      break;

    case NSE_TYPE_WRITE:
      nsock_log_info("Callback: %s %s %sfor EID %li [%s]",
                     nse_type2str(nse->type), nse_status2str(nse->status),
                     errstr, nse->id, get_peeraddr_string(nsi));
      break;

    case NSE_TYPE_TIMER:
      nsock_log_info("Callback: %s %s %sfor EID %li",
                     nse_type2str(nse->type), nse_status2str(nse->status),
                     errstr, nse->id);
      break;

#if HAVE_PCAP
    case NSE_TYPE_PCAP_READ:
      nsock_log_info("Callback: %s %s %sfor EID %li ",
                     nse_type2str(nse->type), nse_status2str(nse->status),
                     errstr, nse->id);
      break;
#endif

    default:
      fatal("Invalid nsock event type (%d)", nse->type);
  }
}
Пример #6
0
/* An event has been completed and the handler is about to be called. This
 * function writes out tracing data about the event if necessary */
void nsock_trace_handler_callback(mspool *ms, msevent *nse) {
  msiod *nsi;
  char *str;
  int strlength = 0;
  char displaystr[256];
  char errstr[256];

  if (ms->tracelevel == 0)
    return;

  nsi = nse->iod;

  if (nse->status == NSE_STATUS_ERROR)
    Snprintf(errstr, sizeof(errstr), "[%s (%d)] ", socket_strerror(nse->errnum), nse->errnum);
  else
    errstr[0] = '\0';

  /* Some types have special tracing treatment */
  switch(nse->type) {
    case NSE_TYPE_CONNECT:
    case NSE_TYPE_CONNECT_SSL:
      nsock_trace(ms, "Callback: %s %s %sfor EID %li [%s]",
                  nse_type2str(nse->type), nse_status2str(nse->status),
                  errstr, nse->id, get_peeraddr_string(nsi));
      break;

    case NSE_TYPE_READ:
      if (nse->status != NSE_STATUS_SUCCESS) {
        if (nsi->peerlen > 0) {
          nsock_trace(ms, "Callback: %s %s %sfor EID %li [%s]",
                      nse_type2str(nse->type), nse_status2str(nse->status),
                      errstr, nse->id, get_peeraddr_string(nsi));
        } else {
          nsock_trace(ms, "Callback: %s %s %sfor EID %li (peer unspecified)",
                      nse_type2str(nse->type), nse_status2str(nse->status),
                      errstr, nse->id);
        }
      } else {
        str = nse_readbuf(nse, &strlength);
        if (ms->tracelevel > 1 && strlength < 80) {
          memcpy(displaystr, ": ", 2);
          memcpy(displaystr + 2, str, strlength);
          displaystr[2 + strlength] = '\0';
          replacenonprintable(displaystr + 2, strlength, '.');
        } else {
          displaystr[0] = '\0';
        }

        if (nsi->peerlen > 0) {
          nsock_trace(ms, "Callback: %s %s for EID %li [%s] %s(%d bytes)%s",
                      nse_type2str(nse->type), nse_status2str(nse->status),
                      nse->id, get_peeraddr_string(nsi),
                      nse_eof(nse)? "[EOF]" : "", strlength, displaystr);
        } else {
          nsock_trace(ms, "Callback %s %s for EID %li (peer unspecified) %s(%d bytes)%s",
                      nse_type2str(nse->type), nse_status2str(nse->status),
                      nse->id, nse_eof(nse)? "[EOF]" : "", strlength, displaystr);
        }
      }
      break;

    case NSE_TYPE_WRITE:
      nsock_trace(ms, "Callback: %s %s %sfor EID %li [%s]",
                  nse_type2str(nse->type), nse_status2str(nse->status), errstr,
                  nse->id, get_peeraddr_string(nsi));
      break;

    case NSE_TYPE_TIMER:
      nsock_trace(ms, "Callback: %s %s %sfor EID %li",
                  nse_type2str(nse->type), nse_status2str(nse->status), errstr,
                  nse->id);
      break;

#if HAVE_PCAP
    case NSE_TYPE_PCAP_READ:
      nsock_trace(ms, "Callback: %s %s %sfor EID %li ",
                  nse_type2str(nse->type), nse_status2str(nse->status),
                  errstr, nse->id);
      break;
#endif

    default:
      assert(0);
      break;
  }
}
Пример #7
0
/* Same as nsock_write except you can use a printf-style format and you can only use this for ASCII strings */
nsock_event_id nsock_printf(nsock_pool ms_pool, nsock_iod ms_iod,
          nsock_ev_handler handler, int timeout_msecs, void *userdata, char *format, ...) {
  mspool *nsp = (mspool *)ms_pool;
  msiod *nsi = (msiod *)ms_iod;
  msevent *nse;
  char buf[4096];
  char *buf2 = NULL;
  int res, res2;
  int strlength = 0;
  char displaystr[256];

  va_list ap;
  va_start(ap,format);

  nse = msevent_new(nsp, NSE_TYPE_WRITE, nsi, timeout_msecs, handler, userdata);
  assert(nse);

  res = Vsnprintf(buf, sizeof(buf), format, ap);
  va_end(ap);

  if (res != -1) {
    if (res > sizeof(buf)) {
      buf2 = (char * )safe_malloc(res + 16);
      res2 = Vsnprintf(buf2, sizeof(buf), format, ap);
      if (res2 == -1 || res2 > res) {
        free(buf2);
        buf2 = NULL;
      } else
        strlength = res2;
    } else {
      buf2 = buf;
      strlength = res;
    }
  }

  if (!buf2) {
    nse->event_done = 1;
    nse->status = NSE_STATUS_ERROR;
    nse->errnum = EMSGSIZE;
  } else {
    if (strlength == 0) {
      nse->event_done = 1;
      nse->status = NSE_STATUS_SUCCESS;
    } else {
      fs_cat(&nse->iobuf, buf2, strlength);
    }
  }

  if (nsp->loglevel == NSOCK_LOG_DBG_ALL && nse->status != NSE_STATUS_ERROR && strlength < 80) {
    memcpy(displaystr, ": ", 2);
    memcpy(displaystr + 2, buf2, strlength);
    displaystr[2 + strlength] = '\0';
    replacenonprintable(displaystr + 2, strlength, '.');
  } else {
    displaystr[0] = '\0';
  }

  nsock_log_debug(nsp, "Write request for %d bytes to IOD #%li EID %li [%s]%s",
                  strlength, nsi->id, nse->id, get_peeraddr_string(nsi), displaystr);

  if (buf2 != buf)
    free(buf2);

  nsp_add_event(nsp, nse);

  return nse->id;
}