Ejemplo n.º 1
0
/** Create log stamp */
void tport_stamp(tport_t const *self, msg_t *msg,
		 char stamp[128], char const *what,
		 size_t n, char const *via,
		 su_time_t now)
{
  char label[24] = "";
  char *comp = "";
  char name[SU_ADDRSIZE] = "";
  su_sockaddr_t const *su;
  unsigned short second, minute, hour;
  /* should check for ifdef HAVE_LOCALTIME_R instead -_- */
#if defined(HAVE_GETTIMEOFDAY) || defined(HAVE_CLOCK_MONOTONIC)
  struct tm nowtm = { 0 };
  time_t nowtime = (now.tv_sec - SU_TIME_EPOCH); /* see su_time0.c 'now' is not really 'now', so we decrease it by SU_TIME_EPOCH */
#endif

  assert(self); assert(msg);

#if defined(HAVE_GETTIMEOFDAY) || defined(HAVE_CLOCK_MONOTONIC)
  localtime_r(&nowtime, &nowtm);
  second = nowtm.tm_sec;
  minute = nowtm.tm_min;
  hour = nowtm.tm_hour;
#else
  second = (unsigned short)(now.tv_sec % 60);
  minute = (unsigned short)((now.tv_sec / 60) % 60);
  hour = (unsigned short)((now.tv_sec / 3600) % 24);
#endif

  su = msg_addr(msg);

#if SU_HAVE_IN6
  if (su->su_family == AF_INET6) {
    if (su->su_sin6.sin6_flowinfo)
      snprintf(label, sizeof(label), "/%u", ntohl(su->su_sin6.sin6_flowinfo));
  }
#endif

  if (msg_addrinfo(msg)->ai_flags & TP_AI_COMPRESSED)
    comp = ";comp=sigcomp";

  su_inet_ntop(su->su_family, SU_ADDR(su), name, sizeof(name));

  snprintf(stamp, 128,
	   "%s "MOD_ZU" bytes %s %s/[%s]:%u%s%s at %02u:%02u:%02u.%06lu:\n",
	   what, (size_t)n, via, self->tp_name->tpn_proto,
	   name, ntohs(su->su_port), label[0] ? label : "", comp,
	   hour, minute, second, now.tv_usec);
}
/** Create log stamp */
void tport_stamp(tport_t const *self, msg_t *msg,
		 char stamp[128], char const *what,
		 size_t n, char const *via,
		 su_time_t now)
{
  char label[24] = "";
  char *comp = "";
  char name[SU_ADDRSIZE] = "";
  su_sockaddr_t const *su;
  unsigned short second, minute, hour;

  assert(self); assert(msg);

  second = (unsigned short)(now.tv_sec % 60);
  minute = (unsigned short)((now.tv_sec / 60) % 60);
  hour = (unsigned short)((now.tv_sec / 3600) % 24);

  su = msg_addr(msg);

#if SU_HAVE_IN6
  if (su->su_family == AF_INET6) {
    if (su->su_sin6.sin6_flowinfo)
      snprintf(label, sizeof(label), "/%u", ntohl(su->su_sin6.sin6_flowinfo));
  }
#endif

  if (msg_addrinfo(msg)->ai_flags & TP_AI_COMPRESSED)
    comp = ";comp=sigcomp";

  su_inet_ntop(su->su_family, SU_ADDR(su), name, sizeof(name));

  snprintf(stamp, 128,
	   "%s "MOD_ZU" bytes %s %s/[%s]:%u%s%s at %02u:%02u:%02u.%06lu:\n",
	   what, (size_t)n, via, self->tp_name->tpn_proto,
	   name, ntohs(su->su_port), label[0] ? label : "", comp,
	   hour, minute, second, now.tv_usec);
}
Ejemplo n.º 3
0
/** Receive datagram.
 *
 * @retval -1 error
 * @retval 0  end-of-stream
 * @retval 1  normal receive (should never happen)
 * @retval 2  incomplete recv, call me again (should never happen)
 * @retval 3  STUN keepalive, ignore
 */
int tport_recv_dgram(tport_t *self)
{
  msg_t *msg;
  ssize_t n, veclen, N;
  su_addrinfo_t *ai;
  su_sockaddr_t *from;
  socklen_t fromlen;
  msg_iovec_t iovec[msg_n_fragments] = {{ 0 }};
  uint8_t sample[1];

  /* Simulate packet loss */
  if (self->tp_params->tpp_drop &&
      (unsigned)su_randint(0, 1000) < self->tp_params->tpp_drop) {
    su_recv(self->tp_socket, sample, 1, 0);
    SU_DEBUG_3(("tport(%p): simulated packet loss!\n", (void *)self));
    return 0;
  }

  assert(self->tp_msg == NULL);

#if nomore
  /* We used to resize the buffer, but it fragments the memory */
  N = 65535;
#else
  N = (ssize_t)su_getmsgsize(self->tp_socket);
  if (N == -1) {
    int err = su_errno();
    SU_DEBUG_1(("%s(%p): su_getmsgsize(): %s (%d)\n", __func__, (void *)self,
		su_strerror(err), err));
    return -1;
  }
  if (N == 0) {
    su_recv(self->tp_socket, sample, 1, 0);
    SU_DEBUG_3(("tport(%p): zero length packet", (void *)self));
    return 0;
  }
#endif

  veclen = tport_recv_iovec(self, &self->tp_msg, iovec, N, 1);
  if (veclen == -1)
    return -1;

  msg = self->tp_msg;

  ai = msg_addrinfo(msg);
  from = (su_sockaddr_t *)ai->ai_addr, fromlen = (socklen_t)(ai->ai_addrlen);

  n = su_vrecv(self->tp_socket, iovec, veclen, 0, from, &fromlen);

  ai->ai_addrlen = fromlen;

  if (n == SOCKET_ERROR) {
    int error = su_errno();
    msg_destroy(msg); self->tp_msg = NULL;
    su_seterrno(error);

    if (su_is_blocking(error))
      return 0;
    else
      return -1;
  }
  else if (n <= 1) {
    SU_DEBUG_1(("%s(%p): runt of "MOD_ZD" bytes\n",
		"tport_recv_dgram", (void *)self, n));
    msg_destroy(msg), self->tp_msg = NULL;
    return 0;
  }

  tport_recv_bytes(self, n, n);

  SU_CANONIZE_SOCKADDR(from);

  if (self->tp_master->mr_dump_file)
    tport_dump_iovec(self, msg, n, iovec, veclen, "recv", "from");

  *sample = *((uint8_t *)iovec[0].mv_base);

  /* Commit received data into buffer. This may relocate iovec contents */
  msg_recv_commit(msg, n, 1);

  if ((sample[0] & 0xf8) == 0xf8)
    /* SigComp */
    return tport_recv_comp_dgram(self, self->tp_comp, &self->tp_msg,
				 from, fromlen);
#if HAVE_SOFIA_STUN
  else if (sample[0] == 0 || sample[0] == 1)
    /* STUN request or response */
    return tport_recv_stun_dgram(self, &self->tp_msg, from, fromlen);
#endif
  else
    return 0;
}