const char *
time_string (time_t t, int usec, bool show_usec, struct gc_arena *gc)
{
  struct buffer out = alloc_buf_gc (64, gc);
  struct timeval tv;

  if (t)
    {
      tv.tv_sec = t;
      tv.tv_usec = usec;
    }
  else
    {
      gettimeofday (&tv, NULL);
    }

  t = tv.tv_sec;
  buf_printf (&out, "%s", ctime(&t));
  buf_rmtail (&out, '\n');

  if (show_usec && tv.tv_usec)
    buf_printf (&out, " us=%d", (int)tv.tv_usec);

  return BSTR (&out);
}
Example #2
0
const char *
format_extended_socket_error (int fd, int *mtu, struct gc_arena *gc)
{
  int res;
  struct probehdr rcvbuf;
  struct iovec iov;
  struct msghdr msg;
  struct cmsghdr *cmsg;
  struct sock_extended_err *e;
  struct sockaddr_in addr;
  struct buffer out = alloc_buf_gc (256, gc);
  char *cbuf = (char *) gc_malloc (256, false, gc);

  *mtu = 0;

  while (true)
    {
      memset (&rcvbuf, -1, sizeof (rcvbuf));
      iov.iov_base = &rcvbuf;
      iov.iov_len = sizeof (rcvbuf);
      msg.msg_name = (uint8_t *) &addr;
      msg.msg_namelen = sizeof (addr);
      msg.msg_iov = &iov;
      msg.msg_iovlen = 1;
      msg.msg_flags = 0;
      msg.msg_control = cbuf;
      msg.msg_controllen = 256; /* size of cbuf */

      res = recvmsg (fd, &msg, MSG_ERRQUEUE);
      if (res < 0)
	goto exit;

      e = NULL;

      for (cmsg = CMSG_FIRSTHDR (&msg); cmsg; cmsg = CMSG_NXTHDR (&msg, cmsg))
	{
	  if (cmsg->cmsg_level == SOL_IP)
	    {
	      if (cmsg->cmsg_type == IP_RECVERR)
		{
		  e = (struct sock_extended_err *) CMSG_DATA (cmsg);
		}
	      else
		{
		  buf_printf (&out ,"CMSG=%d|", cmsg->cmsg_type);
		}
	    }
	}
      if (e == NULL)
	{
	  buf_printf (&out, "NO-INFO|");
	  goto exit;
	}

      switch (e->ee_errno)
	{
	case ETIMEDOUT:
	  buf_printf (&out, "ETIMEDOUT|");
	  break;
	case EMSGSIZE:
	  buf_printf (&out, "EMSGSIZE Path-MTU=%d|", e->ee_info);
	  *mtu = e->ee_info;
	  break;
	case ECONNREFUSED:
	  buf_printf (&out, "ECONNREFUSED|");
	  break;
	case EPROTO:
	  buf_printf (&out, "EPROTO|");
	  break;
	case EHOSTUNREACH:
	  buf_printf (&out, "EHOSTUNREACH|");
	  break;
	case ENETUNREACH:
	  buf_printf (&out, "ENETUNREACH|");
	  break;
	case EACCES:
	  buf_printf (&out, "EACCES|");
	  break;
	default:
	  buf_printf (&out, "UNKNOWN|");
	  break;
	}
    }

 exit:
  buf_rmtail (&out, '|');
  return BSTR (&out);
}