/** 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); }
/** 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; }