Introduce a forth IP packet queue. Urgent packets with

ip_tos == IPTOS_LOWDELAY now get precidence over urgent
packets with ip_tos != IPTOS_LOWDELAY and non-urgent packets
with ip_tos == IPTOS_LOWDELAY.

Enhance the ``set urgent'' syntax to allow for urgent UDP
packets as well as urgent TCP packets.
This commit is contained in:
Brian Somers 1999-09-07 07:51:11 +00:00
parent c057c9b641
commit da47788649
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=51048
6 changed files with 188 additions and 78 deletions

View File

@ -1375,7 +1375,7 @@ static int
SetVariable(struct cmdargs const *arg)
{
long long_val, param = (long)arg->cmd->args;
int mode, dummyint, f;
int mode, dummyint, f, first;
const char *argp;
struct datalink *cx = arg->cx; /* LOCAL_CX uses this */
const char *err = NULL;
@ -1789,18 +1789,40 @@ SetVariable(struct cmdargs const *arg)
break;
case VAR_URGENTPORTS:
if (arg->argn == arg->argc)
ipcp_ClearUrgentPorts(&arg->bundle->ncp.ipcp);
else for (f = arg->argn; f < arg->argc; f++)
if (*arg->argv[f] == '+')
ipcp_AddUrgentPort(&arg->bundle->ncp.ipcp, atoi(arg->argv[f] + 1));
else if (*arg->argv[f] == '-')
ipcp_RemoveUrgentPort(&arg->bundle->ncp.ipcp, atoi(arg->argv[f] + 1));
else {
if (f == arg->argn)
ipcp_ClearUrgentPorts(&arg->bundle->ncp.ipcp);
ipcp_AddUrgentPort(&arg->bundle->ncp.ipcp, atoi(arg->argv[f]));
}
if (arg->argn == arg->argc) {
ipcp_ClearUrgentTcpPorts(&arg->bundle->ncp.ipcp);
ipcp_ClearUrgentUdpPorts(&arg->bundle->ncp.ipcp);
} else if (!strcasecmp(arg->argv[arg->argn], "udp")) {
if (arg->argn == arg->argc - 1)
ipcp_ClearUrgentUdpPorts(&arg->bundle->ncp.ipcp);
else for (f = arg->argn + 1; f < arg->argc; f++)
if (*arg->argv[f] == '+')
ipcp_AddUrgentUdpPort(&arg->bundle->ncp.ipcp, atoi(arg->argv[f] + 1));
else if (*arg->argv[f] == '-')
ipcp_RemoveUrgentUdpPort(&arg->bundle->ncp.ipcp,
atoi(arg->argv[f] + 1));
else {
if (f == arg->argn)
ipcp_ClearUrgentUdpPorts(&arg->bundle->ncp.ipcp);
ipcp_AddUrgentUdpPort(&arg->bundle->ncp.ipcp, atoi(arg->argv[f]));
}
} else {
first = arg->argn;
if (!strcasecmp(arg->argv[first], "tcp") && ++first == arg->argc)
ipcp_ClearUrgentTcpPorts(&arg->bundle->ncp.ipcp);
for (f = first; f < arg->argc; f++)
if (*arg->argv[f] == '+')
ipcp_AddUrgentTcpPort(&arg->bundle->ncp.ipcp, atoi(arg->argv[f] + 1));
else if (*arg->argv[f] == '-')
ipcp_RemoveUrgentTcpPort(&arg->bundle->ncp.ipcp,
atoi(arg->argv[f] + 1));
else {
if (f == first)
ipcp_ClearUrgentTcpPorts(&arg->bundle->ncp.ipcp);
ipcp_AddUrgentTcpPort(&arg->bundle->ncp.ipcp, atoi(arg->argv[f]));
}
}
break;
}
@ -1910,8 +1932,8 @@ static struct cmdtab const SetCommands[] = {
"STOPPED timeouts", "set stopped [LCPseconds [CCPseconds]]"},
{"timeout", NULL, SetVariable, LOCAL_AUTH, "Idle timeout",
"set timeout idletime", (const void *)VAR_IDLETIMEOUT},
{"urgent", NULL, SetVariable, LOCAL_AUTH,
"urgent ports", "set urgent [+|-]port...", (const void *)VAR_URGENTPORTS},
{"urgent", NULL, SetVariable, LOCAL_AUTH, "urgent ports",
"set urgent [tcp|udp] [+|-]port...", (const void *)VAR_URGENTPORTS},
{"vj", NULL, ipcp_vjset, LOCAL_AUTH,
"vj values", "set vj slots|slotcomp [value]"},
{"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH,

View File

@ -339,9 +339,18 @@ PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter)
loglen += strlen(logbuf + loglen);
}
break;
case IPPROTO_UDP:
uh = (struct udphdr *) ptop;
if (pip->ip_tos == IPTOS_LOWDELAY)
pri++;
if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0 &&
ipcp_IsUrgentUdpPort(&bundle->ncp.ipcp, ntohs(uh->uh_sport),
ntohs(uh->uh_dport)))
pri++;
if (logit && loglen < sizeof logbuf) {
uh = (struct udphdr *) ptop;
snprintf(logbuf + loglen, sizeof logbuf - loglen,
"UDP: %s:%d ---> ", inet_ntoa(pip->ip_src), ntohs(uh->uh_sport));
loglen += strlen(logbuf + loglen);
@ -350,6 +359,7 @@ PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter)
loglen += strlen(logbuf + loglen);
}
break;
#ifdef IPPROTO_OSPFIGP
case IPPROTO_OSPFIGP:
if (logit && loglen < sizeof logbuf) {
@ -362,6 +372,7 @@ PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter)
}
break;
#endif
case IPPROTO_IPIP:
if (logit && loglen < sizeof logbuf) {
uh = (struct udphdr *) ptop;
@ -373,6 +384,7 @@ PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter)
loglen += strlen(logbuf + loglen);
}
break;
case IPPROTO_IGMP:
if (logit && loglen < sizeof logbuf) {
uh = (struct udphdr *) ptop;
@ -384,13 +396,15 @@ PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter)
loglen += strlen(logbuf + loglen);
}
break;
case IPPROTO_TCP:
th = (struct tcphdr *) ptop;
if (pip->ip_tos == IPTOS_LOWDELAY)
pri++;
else if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0 &&
ipcp_IsUrgentPort(&bundle->ncp.ipcp, ntohs(th->th_sport),
ntohs(th->th_dport)))
if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0 &&
ipcp_IsUrgentTcpPort(&bundle->ncp.ipcp, ntohs(th->th_sport),
ntohs(th->th_dport)))
pri++;
if (logit && loglen < sizeof logbuf) {

View File

@ -89,7 +89,7 @@
#define issep(ch) ((ch) == ' ' || (ch) == '\t')
#define isip(ch) (((ch) >= '0' && (ch) <= '9') || (ch) == '.')
static u_short default_urgent_ports[] = {
static u_short default_urgent_tcp_ports[] = {
21, /* ftp */
22, /* ssh */
23, /* telnet */
@ -99,77 +99,82 @@ static u_short default_urgent_ports[] = {
544 /* kshell */
};
#define NDEFPORTS (sizeof default_urgent_ports / sizeof default_urgent_ports[0])
static u_short default_urgent_udp_ports[] = { };
#define NDEFTCPPORTS \
(sizeof default_urgent_tcp_ports / sizeof default_urgent_tcp_ports[0])
#define NDEFUDPPORTS \
(sizeof default_urgent_udp_ports / sizeof default_urgent_udp_ports[0])
int
ipcp_IsUrgentPort(struct ipcp *ipcp, u_short src, u_short dst)
ipcp_IsUrgentPort(struct port_range *range, u_short src, u_short dst)
{
int f;
for (f = 0; f < ipcp->cfg.urgent.nports; f++)
if (ipcp->cfg.urgent.port[f] == src || ipcp->cfg.urgent.port[f] == dst)
for (f = 0; f < range->nports; f++)
if (range->port[f] == src || range->port[f] == dst)
return 1;
return 0;
}
void
ipcp_AddUrgentPort(struct ipcp *ipcp, u_short port)
ipcp_AddUrgentPort(struct port_range *range, u_short port)
{
u_short *newport;
int p;
if (ipcp->cfg.urgent.nports == ipcp->cfg.urgent.maxports) {
ipcp->cfg.urgent.maxports += 10;
newport = (u_short *)realloc(ipcp->cfg.urgent.port,
ipcp->cfg.urgent.maxports * sizeof(u_short));
if (range->nports == range->maxports) {
range->maxports += 10;
newport = (u_short *)realloc(range->port,
range->maxports * sizeof(u_short));
if (newport == NULL) {
log_Printf(LogERROR, "ipcp_AddUrgentPort: realloc: %s\n",
strerror(errno));
ipcp->cfg.urgent.maxports -= 10;
range->maxports -= 10;
return;
}
ipcp->cfg.urgent.port = newport;
range->port = newport;
}
for (p = 0; p < ipcp->cfg.urgent.nports; p++)
if (ipcp->cfg.urgent.port[p] == port) {
for (p = 0; p < range->nports; p++)
if (range->port[p] == port) {
log_Printf(LogWARN, "%u: Port already set to urgent\n", port);
break;
} else if (ipcp->cfg.urgent.port[p] > port) {
memmove(ipcp->cfg.urgent.port + p + 1, ipcp->cfg.urgent.port + p,
(ipcp->cfg.urgent.nports - p) * sizeof(u_short));
ipcp->cfg.urgent.port[p] = port;
ipcp->cfg.urgent.nports++;
} else if (range->port[p] > port) {
memmove(range->port + p + 1, range->port + p,
(range->nports - p) * sizeof(u_short));
range->port[p] = port;
range->nports++;
break;
}
if (p == ipcp->cfg.urgent.nports)
ipcp->cfg.urgent.port[ipcp->cfg.urgent.nports++] = port;
if (p == range->nports)
range->port[range->nports++] = port;
}
void
ipcp_RemoveUrgentPort(struct ipcp *ipcp, u_short port)
ipcp_RemoveUrgentPort(struct port_range *range, u_short port)
{
int p;
for (p = 0; p < ipcp->cfg.urgent.nports; p++)
if (ipcp->cfg.urgent.port[p] == port) {
if (p != ipcp->cfg.urgent.nports - 1)
memmove(ipcp->cfg.urgent.port + p, ipcp->cfg.urgent.port + p + 1,
(ipcp->cfg.urgent.nports - p - 1) * sizeof(u_short));
ipcp->cfg.urgent.nports--;
for (p = 0; p < range->nports; p++)
if (range->port[p] == port) {
if (p != range->nports - 1)
memmove(range->port + p, range->port + p + 1,
(range->nports - p - 1) * sizeof(u_short));
range->nports--;
return;
}
if (p == ipcp->cfg.urgent.nports)
if (p == range->nports)
log_Printf(LogWARN, "%u: Port not set to urgent\n", port);
}
void
ipcp_ClearUrgentPorts(struct ipcp *ipcp)
ipcp_ClearUrgentPorts(struct port_range *range)
{
ipcp->cfg.urgent.nports = 0;
range->nports = 0;
}
struct compreq {
@ -401,14 +406,24 @@ ipcp_Show(struct cmdargs const *arg)
inet_ntoa(ipcp->cfg.ns.nbns[0]));
prompt_Printf(arg->prompt, "%s\n", inet_ntoa(ipcp->cfg.ns.nbns[1]));
prompt_Printf(arg->prompt, " Urgent ports: ");
if (ipcp->cfg.urgent.nports == 0)
prompt_Printf(arg->prompt, " Urgent ports\n");
prompt_Printf(arg->prompt, " TCP: ");
if (ipcp->cfg.urgent.tcp.nports == 0)
prompt_Printf(arg->prompt, "none");
else
for (p = 0; p < ipcp->cfg.urgent.nports; p++) {
for (p = 0; p < ipcp->cfg.urgent.tcp.nports; p++) {
if (p)
prompt_Printf(arg->prompt, ", ");
prompt_Printf(arg->prompt, "%u", ipcp->cfg.urgent.port[p]);
prompt_Printf(arg->prompt, "%u", ipcp->cfg.urgent.tcp.port[p]);
}
prompt_Printf(arg->prompt, "\n UDP: ");
if (ipcp->cfg.urgent.udp.nports == 0)
prompt_Printf(arg->prompt, "none");
else
for (p = 0; p < ipcp->cfg.urgent.udp.nports; p++) {
if (p)
prompt_Printf(arg->prompt, ", ");
prompt_Printf(arg->prompt, "%u", ipcp->cfg.urgent.udp.port[p]);
}
prompt_Printf(arg->prompt, "\n\n");
@ -474,10 +489,15 @@ ipcp_Init(struct ipcp *ipcp, struct bundle *bundle, struct link *l,
ipcp->cfg.ns.nbns[0].s_addr = INADDR_ANY;
ipcp->cfg.ns.nbns[1].s_addr = INADDR_ANY;
ipcp->cfg.urgent.nports = ipcp->cfg.urgent.maxports = NDEFPORTS;
ipcp->cfg.urgent.port = (u_short *)malloc(NDEFPORTS * sizeof(u_short));
memcpy(ipcp->cfg.urgent.port, default_urgent_ports,
NDEFPORTS * sizeof(u_short));
ipcp->cfg.urgent.tcp.nports = ipcp->cfg.urgent.tcp.maxports = NDEFTCPPORTS;
ipcp->cfg.urgent.tcp.port = (u_short *)malloc(NDEFTCPPORTS * sizeof(u_short));
memcpy(ipcp->cfg.urgent.tcp.port, default_urgent_tcp_ports,
NDEFTCPPORTS * sizeof(u_short));
ipcp->cfg.urgent.udp.nports = ipcp->cfg.urgent.udp.maxports = NDEFUDPPORTS;
ipcp->cfg.urgent.udp.port = (u_short *)malloc(NDEFUDPPORTS * sizeof(u_short));
memcpy(ipcp->cfg.urgent.udp.port, default_urgent_udp_ports,
NDEFUDPPORTS * sizeof(u_short));
ipcp->cfg.fsm.timeout = DEF_FSMRETRY;
ipcp->cfg.fsm.maxreq = DEF_FSMTRIES;
@ -494,10 +514,15 @@ ipcp_Init(struct ipcp *ipcp, struct bundle *bundle, struct link *l,
void
ipcp_Destroy(struct ipcp *ipcp)
{
if (ipcp->cfg.urgent.maxports) {
ipcp->cfg.urgent.nports = ipcp->cfg.urgent.maxports = 0;
free(ipcp->cfg.urgent.port);
ipcp->cfg.urgent.port = NULL;
if (ipcp->cfg.urgent.tcp.maxports) {
ipcp->cfg.urgent.tcp.nports = ipcp->cfg.urgent.tcp.maxports = 0;
free(ipcp->cfg.urgent.tcp.port);
ipcp->cfg.urgent.tcp.port = NULL;
}
if (ipcp->cfg.urgent.udp.maxports) {
ipcp->cfg.urgent.udp.nports = ipcp->cfg.urgent.udp.maxports = 0;
free(ipcp->cfg.urgent.udp.port);
ipcp->cfg.urgent.udp.port = NULL;
}
}

View File

@ -42,6 +42,12 @@ struct in_range {
int width;
};
struct port_range {
unsigned nports; /* How many ports */
unsigned maxports; /* How many allocated (malloc) ports */
u_short *port; /* The actual ports */
};
struct ipcp {
struct fsm fsm; /* The finite state machine */
@ -70,9 +76,7 @@ struct ipcp {
} ns;
struct {
unsigned nports; /* How many urgent ports */
unsigned maxports; /* How many allocated urgent ports */
u_short *port; /* The urgent ports */
struct port_range tcp, udp; /* The range of urgent ports */
} urgent;
struct fsm_retry fsm; /* How often/frequently to resend requests */
@ -99,7 +103,7 @@ struct ipcp {
u_int32_t my_reject; /* Request codes I have rejected */
struct pppThroughput throughput; /* throughput statistics */
struct mqueue Queue[3]; /* Output packet queues */
struct mqueue Queue[4]; /* Output packet queues */
};
#define fsm2ipcp(fp) (fp->proto == PROTO_IPCP ? (struct ipcp *)fp : NULL)
@ -124,8 +128,25 @@ extern int ipcp_UseHisaddr(struct bundle *, const char *, int);
extern int ipcp_vjset(struct cmdargs const *);
extern void ipcp_CleanInterface(struct ipcp *);
extern int ipcp_InterfaceUp(struct ipcp *);
extern int ipcp_IsUrgentPort(struct ipcp *, u_short, u_short);
extern void ipcp_AddUrgentPort(struct ipcp *, u_short);
extern void ipcp_RemoveUrgentPort(struct ipcp *, u_short);
extern void ipcp_ClearUrgentPorts(struct ipcp *);
extern int ipcp_IsUrgentPort(struct port_range *, u_short, u_short);
extern void ipcp_AddUrgentPort(struct port_range *, u_short);
extern void ipcp_RemoveUrgentPort(struct port_range *, u_short);
extern void ipcp_ClearUrgentPorts(struct port_range *);
extern struct in_addr addr2mask(struct in_addr);
#define ipcp_IsUrgentTcpPort(ipcp, p1, p2) \
ipcp_IsUrgentPort(&(ipcp)->cfg.urgent.tcp, p1, p2)
#define ipcp_IsUrgentUdpPort(ipcp, p1, p2) \
ipcp_IsUrgentPort(&(ipcp)->cfg.urgent.udp, p1, p2)
#define ipcp_AddUrgentTcpPort(ipcp, p) \
ipcp_AddUrgentPort(&(ipcp)->cfg.urgent.tcp, p)
#define ipcp_AddUrgentUdpPort(ipcp, p) \
ipcp_AddUrgentPort(&(ipcp)->cfg.urgent.udp, p)
#define ipcp_RemoveUrgentTcpPort(ipcp, p) \
ipcp_RemoveUrgentPort(&(ipcp)->cfg.urgent.tcp, p)
#define ipcp_RemoveUrgentUdpPort(ipcp, p) \
ipcp_RemoveUrgentPort(&(ipcp)->cfg.urgent.udp, p)
#define ipcp_ClearUrgentTcpPorts(ipcp) \
ipcp_ClearUrgentPorts(&(ipcp)->cfg.urgent.tcp)
#define ipcp_ClearUrgentUdpPorts(ipcp) \
ipcp_ClearUrgentPorts(&(ipcp)->cfg.urgent.udp)

View File

@ -4500,21 +4500,35 @@ is specified,
will never idle out before the link has been up for at least that number
of seconds.
.It set urgent Xo
.Op tcp|udp
.Oo Op +|- Ns
.Ar port
.Oc No ...
.Xc
This command controls the ports that
.Nm
prioritizes when transmitting data. The default priority ports are ports
21 (ftp control), 22 (ssh), 23 (telnet), 513 (login), 514 (shell),
543 (klogin) and 544 (kshell). See
prioritizes when transmitting data. The default priority TCP ports
are ports 21 (ftp control), 22 (ssh), 23 (telnet), 513 (login), 514 (shell),
543 (klogin) and 544 (kshell). There are no priority UDP ports by default.
See
.Xr services 5
for details.
.Pp
If neither
.Dq tcp
or
.Dq udp
are specified,
.Dq tcp
is assumed.
.Pp
If no
.Ar port Ns No s
are given, the priority port list is cleared. If the first
are given, the priority port lists are cleared (although if
.Dq tcp
or
.Dq udp
is specified, only that list is cleared). If the first
.Ar port
argument is prefixed with a plus
.Pq Dq \&+

View File

@ -4500,21 +4500,35 @@ is specified,
will never idle out before the link has been up for at least that number
of seconds.
.It set urgent Xo
.Op tcp|udp
.Oo Op +|- Ns
.Ar port
.Oc No ...
.Xc
This command controls the ports that
.Nm
prioritizes when transmitting data. The default priority ports are ports
21 (ftp control), 22 (ssh), 23 (telnet), 513 (login), 514 (shell),
543 (klogin) and 544 (kshell). See
prioritizes when transmitting data. The default priority TCP ports
are ports 21 (ftp control), 22 (ssh), 23 (telnet), 513 (login), 514 (shell),
543 (klogin) and 544 (kshell). There are no priority UDP ports by default.
See
.Xr services 5
for details.
.Pp
If neither
.Dq tcp
or
.Dq udp
are specified,
.Dq tcp
is assumed.
.Pp
If no
.Ar port Ns No s
are given, the priority port list is cleared. If the first
are given, the priority port lists are cleared (although if
.Dq tcp
or
.Dq udp
is specified, only that list is cleared). If the first
.Ar port
argument is prefixed with a plus
.Pq Dq \&+