mirror of
https://frontier.innolan.net/rainlance/amiga-ntimed.git
synced 2026-05-03 04:20:57 +00:00
Pass the expected socket family into UdpTimedRx() so it can pick the
right socket, rather than listening on both. Implement TODO_Cancel() Only wake the time_unix task when needed. Fix sockaddr comparison for IPv6[1] Grap userland timestamp, in case SCM_TIMESTAMP* does not work/isn't available.[1] Undefined timestamp fix for simfile reading[1] Minor fixes from github [1] From Ronan Flood
This commit is contained in:
@@ -135,7 +135,7 @@ Packet traces and simulations
|
|||||||
|
|
||||||
You can also run the program two other ways::
|
You can also run the program two other ways::
|
||||||
|
|
||||||
./Ntimed-client --poll-server some_ntp_server some_other_ntp_server
|
./ntimed-client --poll-server some_ntp_server some_other_ntp_server
|
||||||
|
|
||||||
This will *not* steer your clock, but it will query the servers as
|
This will *not* steer your clock, but it will query the servers as
|
||||||
if it should have steered your clock. (Ntpd should *not* be running
|
if it should have steered your clock. (Ntpd should *not* be running
|
||||||
@@ -145,7 +145,7 @@ but you can control that with "-d 3600" for one hour etc.
|
|||||||
If you save the output into a file (redirect stdout or use '-t filename'),
|
If you save the output into a file (redirect stdout or use '-t filename'),
|
||||||
you can use it as input for a simulation run::
|
you can use it as input for a simulation run::
|
||||||
|
|
||||||
./Ntimed-client --sim-client -s filename -t /tmp/_
|
./ntimed-client --sim-client -s filename -t /tmp/_
|
||||||
|
|
||||||
And then run::
|
And then run::
|
||||||
|
|
||||||
@@ -200,7 +200,7 @@ in dire straits after Dave Mills retired.
|
|||||||
Thanks for giving me money and free hands to do what I thought was
|
Thanks for giving me money and free hands to do what I thought was
|
||||||
best -- even though I am a "BSD-guy".
|
best -- even though I am a "BSD-guy".
|
||||||
|
|
||||||
Thanks to Harlan Steen for keeping the NTPD flame burning, however
|
Thanks to Harlan Stenn for keeping the NTPD flame burning, however
|
||||||
stormy the last decade has been.
|
stormy the last decade has been.
|
||||||
|
|
||||||
I trust The Network Time Foundation will take as good care of Ntimed
|
I trust The Network Time Foundation will take as good care of Ntimed
|
||||||
|
|||||||
3
configure
vendored
3
configure
vendored
@@ -67,6 +67,7 @@ SRCS='
|
|||||||
ocx_stdio.c
|
ocx_stdio.c
|
||||||
param.c
|
param.c
|
||||||
pll_std.c
|
pll_std.c
|
||||||
|
suckaddr.c
|
||||||
time_sim.c
|
time_sim.c
|
||||||
time_stuff.c
|
time_stuff.c
|
||||||
time_unix.c
|
time_unix.c
|
||||||
@@ -100,7 +101,7 @@ if $BSD ; then
|
|||||||
echo '.include <bsd.prog.mk>'
|
echo '.include <bsd.prog.mk>'
|
||||||
) > Makefile
|
) > Makefile
|
||||||
|
|
||||||
msg=", remeber to run 'make depend'"
|
msg=", remember to run 'make depend'"
|
||||||
else
|
else
|
||||||
(
|
(
|
||||||
echo '# Portable Makefile generated by configure'
|
echo '# Portable Makefile generated by configure'
|
||||||
|
|||||||
17
ntimed.h
17
ntimed.h
@@ -89,6 +89,10 @@ extern pll_f *PLL;
|
|||||||
|
|
||||||
void PLL_Init(void);
|
void PLL_Init(void);
|
||||||
|
|
||||||
|
/* suckaddr.c -- Sockaddr utils ***************************************/
|
||||||
|
|
||||||
|
int SA_Equal(const void *sa1, size_t sl1, const void *sa2, size_t sl2);
|
||||||
|
|
||||||
/* time_sim.c -- Simulated timebase ***********************************/
|
/* time_sim.c -- Simulated timebase ***********************************/
|
||||||
|
|
||||||
extern double Time_Sim_delta;
|
extern double Time_Sim_delta;
|
||||||
@@ -145,11 +149,16 @@ typedef enum todo_e todo_f(struct ocx *, struct todolist *, void *priv);
|
|||||||
|
|
||||||
struct todolist *TODO_NewList(void);
|
struct todolist *TODO_NewList(void);
|
||||||
|
|
||||||
struct todo *TODO_ScheduleRel(struct todolist *, todo_f *func, void *priv,
|
uintptr_t TODO_ScheduleRel(struct todolist *,
|
||||||
double when, double repeat, const char *fmt, ...);
|
todo_f *func, void *priv,
|
||||||
struct todo *TODO_ScheduleAbs(struct todolist *, todo_f *func, void *priv,
|
double when, double repeat,
|
||||||
const struct timestamp *when, double repeat, const char *fmt, ...);
|
const char *fmt, ...) __printflike(6, 7);
|
||||||
|
uintptr_t TODO_ScheduleAbs(struct todolist *,
|
||||||
|
todo_f *func, void *priv,
|
||||||
|
const struct timestamp *when, double repeat,
|
||||||
|
const char *fmt, ...) __printflike(6, 7);
|
||||||
enum todo_e TODO_Run(struct ocx *ocx, struct todolist *);
|
enum todo_e TODO_Run(struct ocx *ocx, struct todolist *);
|
||||||
|
void TODO_Cancel(struct todolist *tdl, uintptr_t *);
|
||||||
|
|
||||||
/* combine_delta.c -- Source Combiner based on delta-pdfs *************/
|
/* combine_delta.c -- Source Combiner based on delta-pdfs *************/
|
||||||
|
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ NTP_Peer_Poll(struct ocx *ocx, const struct udp_socket *usc,
|
|||||||
(void)TB_Now(&t1);
|
(void)TB_Now(&t1);
|
||||||
d = TS_Diff(&t1, &t0);
|
d = TS_Diff(&t1, &t0);
|
||||||
|
|
||||||
i = UdpTimedRx(ocx, usc, &rss, &rssl, &t2,
|
i = UdpTimedRx(ocx, usc, np->sa->sa_family, &rss, &rssl, &t2,
|
||||||
buf, sizeof buf, tmo - d);
|
buf, sizeof buf, tmo - d);
|
||||||
|
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
@@ -149,7 +149,7 @@ NTP_Peer_Poll(struct ocx *ocx, const struct udp_socket *usc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Ignore packets from other hosts */
|
/* Ignore packets from other hosts */
|
||||||
if (np->sa_len != rssl || memcmp(np->sa, &rss, rssl))
|
if (!SA_Equal(np->sa, np->sa_len, &rss, rssl))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
AN(NTP_Packet_Unpack(np->rx_pkt, buf, i));
|
AN(NTP_Packet_Unpack(np->rx_pkt, buf, i));
|
||||||
|
|||||||
@@ -82,13 +82,13 @@ NTP_Tool_Format(char *p, ssize_t len, const struct ntp_packet *pkt)
|
|||||||
|
|
||||||
e = p + len;
|
e = p + len;
|
||||||
|
|
||||||
p += snprintf(p, e - p, "[%u", pkt->ntp_leap);
|
p += snprintf(p, e - p, "[%d", pkt->ntp_leap);
|
||||||
assert(p < e);
|
assert(p < e);
|
||||||
|
|
||||||
p += snprintf(p, e - p, " %u", pkt->ntp_version);
|
p += snprintf(p, e - p, " %u", pkt->ntp_version);
|
||||||
assert(p < e);
|
assert(p < e);
|
||||||
|
|
||||||
p += snprintf(p, e - p, " %u", pkt->ntp_mode);
|
p += snprintf(p, e - p, " %d", pkt->ntp_mode);
|
||||||
assert(p < e);
|
assert(p < e);
|
||||||
|
|
||||||
p += snprintf(p, e - p, " %3u", pkt->ntp_stratum);
|
p += snprintf(p, e - p, " %3u", pkt->ntp_stratum);
|
||||||
@@ -196,6 +196,7 @@ NTP_Tool_Scan(struct ntp_packet *pkt, const char *buf)
|
|||||||
if (d_fields[6] != 0.0) {
|
if (d_fields[6] != 0.0) {
|
||||||
pkt->ts_rx = pkt->ntp_transmit;
|
pkt->ts_rx = pkt->ntp_transmit;
|
||||||
TS_Add(&pkt->ts_rx, d_fields[6]);
|
TS_Add(&pkt->ts_rx, d_fields[6]);
|
||||||
}
|
} else
|
||||||
|
INIT_OBJ(&pkt->ts_rx, TIMESTAMP_MAGIC);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
*
|
*
|
||||||
* About this implementation:
|
* About this implementation:
|
||||||
*
|
*
|
||||||
* This is a very naiive implementation spitting things out to stdout/stderr,
|
* This is a very naive implementation spitting things out to stdout/stderr,
|
||||||
* knowing that we are a single threaded program.
|
* knowing that we are a single threaded program.
|
||||||
*
|
*
|
||||||
* XXX: Pull in sbufs to do it right.
|
* XXX: Pull in sbufs to do it right.
|
||||||
|
|||||||
84
suckaddr.c
Normal file
84
suckaddr.c
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Poul-Henning Kamp
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The world has not enough cuss-words to precisely convey how broken the
|
||||||
|
* the struct sockaddr concept is.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <sys/types.h> /* Compat for OpenBSD */
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#include "ntimed.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
SA_Equal(const void *sa1, size_t sl1, const void *sa2, size_t sl2)
|
||||||
|
{
|
||||||
|
const struct sockaddr *s1, *s2;
|
||||||
|
const struct sockaddr_in *s41, *s42;
|
||||||
|
const struct sockaddr_in6 *s61, *s62;
|
||||||
|
|
||||||
|
AN(sa1);
|
||||||
|
AN(sa2);
|
||||||
|
assert(sl1 >= sizeof(struct sockaddr));
|
||||||
|
assert(sl2 >= sizeof(struct sockaddr));
|
||||||
|
|
||||||
|
s1 = sa1;
|
||||||
|
s2 = sa2;
|
||||||
|
if (s1->sa_family != s2->sa_family)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
if (s1->sa_family == AF_INET) {
|
||||||
|
assert(sl1 >= sizeof(struct sockaddr_in));
|
||||||
|
assert(sl2 >= sizeof(struct sockaddr_in));
|
||||||
|
s41 = sa1;
|
||||||
|
s42 = sa2;
|
||||||
|
if (s41->sin_port != s42->sin_port)
|
||||||
|
return (0);
|
||||||
|
if (memcmp(&s41->sin_addr, &s42->sin_addr,
|
||||||
|
sizeof s41->sin_addr))
|
||||||
|
return (0);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s1->sa_family == AF_INET6) {
|
||||||
|
assert(sl1 >= sizeof(struct sockaddr_in6));
|
||||||
|
assert(sl2 >= sizeof(struct sockaddr_in6));
|
||||||
|
s61 = sa1;
|
||||||
|
s62 = sa2;
|
||||||
|
if (s61->sin6_port != s62->sin6_port)
|
||||||
|
return (0);
|
||||||
|
if (s61->sin6_scope_id != s62->sin6_scope_id)
|
||||||
|
return (0);
|
||||||
|
if (memcmp(&s61->sin6_addr, &s62->sin6_addr,
|
||||||
|
sizeof s61->sin6_addr))
|
||||||
|
return (0);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
47
time_unix.c
47
time_unix.c
@@ -46,6 +46,9 @@ static double adj_offset = 0;
|
|||||||
static double adj_duration = 0;
|
static double adj_duration = 0;
|
||||||
static double adj_freq = 0;
|
static double adj_freq = 0;
|
||||||
|
|
||||||
|
static uintptr_t ticker;
|
||||||
|
static struct todolist *kt_tdl;
|
||||||
|
|
||||||
// #undef CLOCK_REALTIME /* Test old unix code */
|
// #undef CLOCK_REALTIME /* Test old unix code */
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
@@ -70,7 +73,7 @@ static double adj_freq = 0;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
kt_setfreq(double frequency)
|
kt_setfreq(struct ocx *ocx, double frequency)
|
||||||
{
|
{
|
||||||
struct timex tx;
|
struct timex tx;
|
||||||
int i;
|
int i;
|
||||||
@@ -90,46 +93,47 @@ kt_setfreq(double frequency)
|
|||||||
tx.freq = (long)floor(frequency * (65536 * 1e6));
|
tx.freq = (long)floor(frequency * (65536 * 1e6));
|
||||||
errno = 0;
|
errno = 0;
|
||||||
i = ntp_adjtime(&tx);
|
i = ntp_adjtime(&tx);
|
||||||
|
Put(ocx, OCX_TRACE, "KERNPLL %.6e %d\n", frequency, i);
|
||||||
/* XXX: what is the correct error test here ? */
|
/* XXX: what is the correct error test here ? */
|
||||||
assert(i >= 0);
|
assert(i >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum todo_e __match_proto__(todo_f)
|
static enum todo_e __match_proto__(todo_f)
|
||||||
kt_pll(struct ocx *ocx, struct todolist *tdl, void *priv)
|
kt_ticker(struct ocx *ocx, struct todolist *tdl, void *priv)
|
||||||
{
|
{
|
||||||
double d, freq;
|
|
||||||
struct timestamp ts;
|
|
||||||
char buf[40];
|
|
||||||
|
|
||||||
(void)ocx;
|
(void)ocx;
|
||||||
AN(tdl);
|
AN(tdl);
|
||||||
AZ(priv);
|
AZ(priv);
|
||||||
freq = adj_freq;
|
kt_setfreq(ocx, adj_freq);
|
||||||
if (adj_duration > 0.0) {
|
ticker = 0;
|
||||||
d = adj_offset / adj_duration;
|
|
||||||
freq += d;
|
|
||||||
adj_offset -= d;
|
|
||||||
adj_duration -= 1.0;
|
|
||||||
}
|
|
||||||
TB_Now(&ts);
|
|
||||||
TS_Format(buf, sizeof buf, &ts);
|
|
||||||
Put(ocx, OCX_TRACE, "KERNTIME_PLL %s %.6e %.6e %.3e %.6e\n",
|
|
||||||
buf, adj_freq, adj_offset, adj_duration, freq);
|
|
||||||
kt_setfreq(freq);
|
|
||||||
return (TODO_OK);
|
return (TODO_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __match_proto__(tb_adjust_f)
|
static void __match_proto__(tb_adjust_f)
|
||||||
kt_adjust(struct ocx *ocx, double offset, double duration, double frequency)
|
kt_adjust(struct ocx *ocx, double offset, double duration, double frequency)
|
||||||
{
|
{
|
||||||
|
double freq;
|
||||||
|
|
||||||
(void)ocx;
|
(void)ocx;
|
||||||
|
assert(duration >= 0.0);
|
||||||
|
|
||||||
|
if (ticker)
|
||||||
|
TODO_Cancel(kt_tdl, &ticker);
|
||||||
|
|
||||||
adj_offset = offset;
|
adj_offset = offset;
|
||||||
adj_duration = floor(duration);
|
adj_duration = floor(duration);
|
||||||
if (adj_offset > 0.0 && adj_duration == 0.0)
|
if (adj_offset > 0.0 && adj_duration == 0.0)
|
||||||
adj_duration = 1.0;
|
adj_duration = 1.0;
|
||||||
adj_freq = frequency;
|
adj_freq = frequency;
|
||||||
|
|
||||||
|
freq = adj_freq;
|
||||||
|
if (adj_duration > 0.0)
|
||||||
|
freq += adj_offset / adj_duration;
|
||||||
|
kt_setfreq(ocx, freq);
|
||||||
|
if (adj_duration > 0.0)
|
||||||
|
ticker = TODO_ScheduleRel(kt_tdl, kt_ticker, NULL,
|
||||||
|
adj_duration, 0.0, "KT_TICK");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
@@ -229,18 +233,15 @@ kt_sleep(double dur)
|
|||||||
void
|
void
|
||||||
Time_Unix(struct todolist *tdl)
|
Time_Unix(struct todolist *tdl)
|
||||||
{
|
{
|
||||||
struct timestamp ts;
|
|
||||||
|
|
||||||
|
AN(tdl);
|
||||||
TB_Step = kt_step;
|
TB_Step = kt_step;
|
||||||
TB_Adjust = kt_adjust;
|
TB_Adjust = kt_adjust;
|
||||||
TB_Sleep = kt_sleep;
|
TB_Sleep = kt_sleep;
|
||||||
TB_Now = kt_now;
|
TB_Now = kt_now;
|
||||||
|
kt_tdl = tdl;
|
||||||
|
|
||||||
/* Aim the userland PLL wrangler at 125msec before the second */
|
/* XXX: test if we have perms */
|
||||||
TB_Now(&ts);
|
|
||||||
ts.sec += 1;
|
|
||||||
ts.frac = 14ULL << 60ULL;
|
|
||||||
(void)TODO_ScheduleAbs(tdl, kt_pll, NULL, &ts, 1.0, "SIMPLL");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
|
|||||||
35
todo.c
35
todo.c
@@ -28,6 +28,8 @@
|
|||||||
*
|
*
|
||||||
* This is a simple "TODO-list" scheduler for calling things at certain
|
* This is a simple "TODO-list" scheduler for calling things at certain
|
||||||
* times. Jobs can be one-shot or repeated and repeated jobs can abort.
|
* times. Jobs can be one-shot or repeated and repeated jobs can abort.
|
||||||
|
*
|
||||||
|
* For ease of debugging, TODO jobs have a name.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@@ -81,13 +83,30 @@ todo_insert(struct todolist *tdl, struct todo *tp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* Return a pointer to the todo item, so the API can support cancellation.
|
|
||||||
* (Cancellation will be necessary for NTP-peer removal)
|
|
||||||
*
|
|
||||||
* For ease of debugging, TODO jobs have a name.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct todo *
|
void
|
||||||
|
TODO_Cancel(struct todolist *tdl, uintptr_t *tp)
|
||||||
|
{
|
||||||
|
struct todo *tp2;
|
||||||
|
|
||||||
|
CHECK_OBJ_NOTNULL(tdl, TODOLIST_MAGIC);
|
||||||
|
AN(tp);
|
||||||
|
AN(*tp);
|
||||||
|
|
||||||
|
TAILQ_FOREACH(tp2, &tdl->todolist, list)
|
||||||
|
if ((uintptr_t)tp2 == *tp)
|
||||||
|
break;
|
||||||
|
CHECK_OBJ_NOTNULL(tp2, TODO_MAGIC);
|
||||||
|
TAILQ_REMOVE(&tdl->todolist, tp2, list);
|
||||||
|
FREE_OBJ(tp2);
|
||||||
|
*tp = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
uintptr_t
|
||||||
TODO_ScheduleAbs(struct todolist *tdl, todo_f *func, void *priv,
|
TODO_ScheduleAbs(struct todolist *tdl, todo_f *func, void *priv,
|
||||||
const struct timestamp *when, double repeat, const char *fmt, ...)
|
const struct timestamp *when, double repeat, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
@@ -110,10 +129,10 @@ TODO_ScheduleAbs(struct todolist *tdl, todo_f *func, void *priv,
|
|||||||
(void)vsnprintf(tp->what, sizeof tp->what, fmt, ap);
|
(void)vsnprintf(tp->what, sizeof tp->what, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
todo_insert(tdl, tp);
|
todo_insert(tdl, tp);
|
||||||
return (tp);
|
return ((uintptr_t)tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct todo *
|
uintptr_t
|
||||||
TODO_ScheduleRel(struct todolist *tdl, todo_f *func, void *priv,
|
TODO_ScheduleRel(struct todolist *tdl, todo_f *func, void *priv,
|
||||||
double when, double repeat, const char *fmt, ...)
|
double when, double repeat, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
@@ -137,7 +156,7 @@ TODO_ScheduleRel(struct todolist *tdl, todo_f *func, void *priv,
|
|||||||
(void)vsnprintf(tp->what, sizeof tp->what, fmt, ap);
|
(void)vsnprintf(tp->what, sizeof tp->what, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
todo_insert(tdl, tp);
|
todo_insert(tdl, tp);
|
||||||
return (tp);
|
return ((uintptr_t)tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
|
|||||||
43
udp.c
43
udp.c
@@ -86,6 +86,7 @@ UdpTimedSocket(struct ocx *ocx)
|
|||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
UdpTimedRx(struct ocx *ocx, const struct udp_socket *usc,
|
UdpTimedRx(struct ocx *ocx, const struct udp_socket *usc,
|
||||||
|
sa_family_t fam,
|
||||||
struct sockaddr_storage *ss, socklen_t *sl,
|
struct sockaddr_storage *ss, socklen_t *sl,
|
||||||
struct timestamp *ts, void *buf, ssize_t len, double tmo)
|
struct timestamp *ts, void *buf, ssize_t len, double tmo)
|
||||||
{
|
{
|
||||||
@@ -94,9 +95,9 @@ UdpTimedRx(struct ocx *ocx, const struct udp_socket *usc,
|
|||||||
struct cmsghdr *cmsg;
|
struct cmsghdr *cmsg;
|
||||||
u_char ctrl[1024];
|
u_char ctrl[1024];
|
||||||
ssize_t rl;
|
ssize_t rl;
|
||||||
int i, j;
|
int i;
|
||||||
int tmo_msec;
|
int tmo_msec;
|
||||||
struct pollfd pfd[2];
|
struct pollfd pfd[1];
|
||||||
|
|
||||||
CHECK_OBJ_NOTNULL(usc, UDP_SOCKET_MAGIC);
|
CHECK_OBJ_NOTNULL(usc, UDP_SOCKET_MAGIC);
|
||||||
AN(ss);
|
AN(ss);
|
||||||
@@ -105,18 +106,15 @@ UdpTimedRx(struct ocx *ocx, const struct udp_socket *usc,
|
|||||||
AN(buf);
|
AN(buf);
|
||||||
assert(len > 0);
|
assert(len > 0);
|
||||||
|
|
||||||
|
if (fam == AF_INET)
|
||||||
|
pfd[0].fd = usc->fd4;
|
||||||
|
else if (fam == AF_INET6)
|
||||||
|
pfd[0].fd = usc->fd6;
|
||||||
|
else
|
||||||
|
WRONG("Wrong family in UdpTimedRx");
|
||||||
|
|
||||||
j = 0;
|
pfd[0].events = POLLIN;
|
||||||
if (usc->fd4 >= 0) {
|
pfd[0].revents = 0;
|
||||||
pfd[j].fd = usc->fd4;
|
|
||||||
pfd[j].events = POLLIN;
|
|
||||||
pfd[j++].revents = 0;
|
|
||||||
}
|
|
||||||
if (usc->fd6 >= 0) {
|
|
||||||
pfd[j].fd = usc->fd6;
|
|
||||||
pfd[j].events = POLLIN;
|
|
||||||
pfd[j++].revents = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tmo == 0.0) {
|
if (tmo == 0.0) {
|
||||||
tmo_msec = -1;
|
tmo_msec = -1;
|
||||||
@@ -125,7 +123,7 @@ UdpTimedRx(struct ocx *ocx, const struct udp_socket *usc,
|
|||||||
if (tmo_msec <= 0)
|
if (tmo_msec <= 0)
|
||||||
tmo_msec = 0;
|
tmo_msec = 0;
|
||||||
}
|
}
|
||||||
i = poll(pfd, j, tmo_msec);
|
i = poll(pfd, 1, tmo_msec);
|
||||||
|
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
Fail(ocx, 1, "poll(2) failed\n");
|
Fail(ocx, 1, "poll(2) failed\n");
|
||||||
@@ -133,6 +131,9 @@ UdpTimedRx(struct ocx *ocx, const struct udp_socket *usc,
|
|||||||
if (i == 0)
|
if (i == 0)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
|
/* Grab a timestamp in case none of the SCM_TIMESTAMP* works */
|
||||||
|
TB_Now(ts);
|
||||||
|
|
||||||
memset(&msg, 0, sizeof msg);
|
memset(&msg, 0, sizeof msg);
|
||||||
msg.msg_name = (void*)ss;
|
msg.msg_name = (void*)ss;
|
||||||
msg.msg_namelen = sizeof *ss;
|
msg.msg_namelen = sizeof *ss;
|
||||||
@@ -145,19 +146,17 @@ UdpTimedRx(struct ocx *ocx, const struct udp_socket *usc,
|
|||||||
memset(ctrl, 0, sizeof ctrl);
|
memset(ctrl, 0, sizeof ctrl);
|
||||||
cmsg = (void*)ctrl;
|
cmsg = (void*)ctrl;
|
||||||
|
|
||||||
for (i = 0; i < j; i++)
|
rl = recvmsg(pfd[0].fd, &msg, 0);
|
||||||
if (pfd[i].revents & POLLIN)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (i == j)
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
rl = recvmsg(pfd[i].fd, &msg, 0);
|
|
||||||
if (rl <= 0)
|
if (rl <= 0)
|
||||||
return (rl);
|
return (rl);
|
||||||
|
|
||||||
*sl = msg.msg_namelen;
|
*sl = msg.msg_namelen;
|
||||||
|
|
||||||
|
if (msg.msg_flags != 0) {
|
||||||
|
Debug(ocx, "msg_flags = 0x%x", msg.msg_flags);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
for(;cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
for(;cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
||||||
#ifdef SCM_TIMESTAMPNS
|
#ifdef SCM_TIMESTAMPNS
|
||||||
if (cmsg->cmsg_level == SOL_SOCKET &&
|
if (cmsg->cmsg_level == SOL_SOCKET &&
|
||||||
|
|||||||
1
udp.h
1
udp.h
@@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
struct udp_socket *UdpTimedSocket(struct ocx *ocx);
|
struct udp_socket *UdpTimedSocket(struct ocx *ocx);
|
||||||
ssize_t UdpTimedRx(struct ocx *, const struct udp_socket *,
|
ssize_t UdpTimedRx(struct ocx *, const struct udp_socket *,
|
||||||
|
sa_family_t fam,
|
||||||
struct sockaddr_storage *, socklen_t *,
|
struct sockaddr_storage *, socklen_t *,
|
||||||
struct timestamp *,
|
struct timestamp *,
|
||||||
void *, ssize_t len,
|
void *, ssize_t len,
|
||||||
|
|||||||
Reference in New Issue
Block a user