Re: hackers-digest V1 #1013

Started by Paul A Vixieover 27 years ago53 messages
#1Paul A Vixie
paul@vix.com

i would very much like inet_net_pton to not be changed in this way,
even though it's an internal server function the way postgres 6.4
will be packaged. there is an RFC specifying what this function does.

#2Noname
darcy@druid.net
In reply to: Paul A Vixie (#1)
Re: [HACKERS] Re: hackers-digest V1 #1013

Thus spake Paul A Vixie

i would very much like inet_net_pton to not be changed in this way,

You mean inet_net_ntop, right?

even though it's an internal server function the way postgres 6.4
will be packaged. there is an RFC specifying what this function does.

Are you talking about RFC2133? That one doesn't even specify bits as
an argument so this is already different. Is there another one I
should be looking at?

If a function is based on a standards document like this, shouldn't
we include that as a comment in the file?

Anyway, I seem to be mistaken about the whole cidr or inet type.
Based on the discussions we had earlier I am surprised by the
following.

darcy=> select '198.1.2.3/8'::inet;
?column?
--------
198/8
(1 row)

I would have expected it to print what I entered. If the above is
correct then perhaps we still need a cidr type that behaves differently
or rename this to cidr and write a new inet type.

Here is what I thought we were talking about taken from postings in
this list back in July.

From Bruce Momjian:
My guess is that it is going to output x.x.x.x/32, but we should supply
a function so they can get just the IP or the mask from the type. That
way, people who don't want the cidr format can pull out the part they
want.

This suggests that the whole address is stored and by default would be
output. Are we outputting just the network part now and expecting my
functions to get the host part?

I said:

Perhaps there is an underlying difference of assumptions about what
the actual type is. Let me take a stab at defining it (without
naming it) and see if we're all on the same bus.

I see the underlying data type storing two things, a host address
(which can hold an IPv4 or IPv6 IP) and a netmask which can be
stored as a small int, 8 bits is plenty. The input function would
read IP numbers as follows (I'm making some of this up as I go.)

x.x.x.x/y IP x.x.x.x with masklen y
x.x.x.x:y.y.y.y IP x.x.x.x with masklen determined by examining
y.y.y.y raising an exception if it is an invalid
mask (defined as all ones followed by all zeroes)
x.x.x.x IP x.x.x.x masklen of 32

The output functions would print in a standard way, possibly allowing
alternate representations like we do for money. Also, there would
be functions to extract the host, the network or the netmask.

Is this close to what everyone thinks or are we talking about completely
different things?

No one contradicted me so I assumed that there was agreement.

From Bruce Momjian:
That way, if they specify cidr bits, we store it. If they don't we make
the bits field equal -1, and print/sort appropriately. The addr len is
usually 3, but ip6 is also easy to add by making the addr len equal 6.

Supporting the idea of setting bits to -1 to mean an unspecified netmask.

I also checked doc/README.inet. It seems to support what I expect
although it doesn't mention setting bits to -1.

So what do I do? Should I redo the inet functions without using the
inet_net_* functions as described above or is the current behaviour the
one we wanted?

-- 
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 424 2871     (DoD#0082)    (eNTP)   |  what's for dinner.
#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Noname (#2)
Re: [HACKERS] Re: hackers-digest V1 #1013

darcy@druid.net (D'Arcy J.M. Cain) writes:

Based on the discussions we had earlier I am surprised by the
following.

darcy=> select '198.1.2.3/8'::inet;
?column?
--------
198/8
(1 row)

I would have expected it to print what I entered.

Why? You told it to truncate the data to 8 bits, so it did. (At least,
that's my understanding of what the /n notation means, but maybe I'm
mistaken.)

regards, tom lane

#4Noname
darcy@druid.net
In reply to: Tom Lane (#3)
Re: [HACKERS] Re: hackers-digest V1 #1013

Thus spake Tom Lane

darcy@druid.net (D'Arcy J.M. Cain) writes:

Based on the discussions we had earlier I am surprised by the
following.

darcy=> select '198.1.2.3/8'::inet;
?column?
--------
198/8
(1 row)

I would have expected it to print what I entered.

Why? You told it to truncate the data to 8 bits, so it did. (At least,
that's my understanding of what the /n notation means, but maybe I'm
mistaken.)

As I explained, I was surprised based on my understanding of the type
based on previous postings.

BTW, for a real world example of the usage I was expecting, look at an
Ascend router. In a connection profile you can specify an IP for the
remote side as, e.g., 198.96.119.225/28. The Ascend pulls out all
the information it needs to set up that connection. It assigns
198.96.119.225 to the remote host, it routes the 16 addresses in that
subnet to that interface and, if RIP is enabled (a bad idea but allowed)
then it knows to announce on 198.96.119.239.

-- 
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 424 2871     (DoD#0082)    (eNTP)   |  what's for dinner.
#5Paul A Vixie
paul@vix.com
In reply to: Noname (#2)
Re: inet/cidr/bind

my take on this is that (1) inet_net_pton() is definitely broken in that
it is willing to write one more byte of output than its arguments allow,
and (2) inet_net_{pton,ntop}() is not suitable for postgresql's use here.

i can fix (1) in bind 8.1.3, and postgresql already has it fixed in its
version of bind's library.

there is no way to fix (2) without an api change. we need, in order to
meet the stated needs of folks here who have uses for an inet-like type,
a way to have the prefix length be less than the size of the bitstring
being introduced. "16.1.0.2/28" was given as an example, that being a
way to give both a host address and its netmask on some wire. i've
wanted this functionality from time to time in the past and i can see
why for postgresql's purposes that's what should be provided for the
"inet" (or, given this change, more properly the "cidr") type.

but inet_net_ntop() only returns one thing (the prefix length) and the
caller is expected to know how many octets of mantissa were generated
based on this returned prefix length. i propose a new interface, which
would have a different name, a different argument list, and a different
use:

int
inet_cidr_pton(af, src, dst, size, int *used)

this would work very much the same as inet_net_pton() except for three
things: (1) nonzero trailing mantissas (host parts) would be allowed; (2)
the number of consumed octets of dst would be set into *used; and (3) there
would be absolutely no classful assumptions made if the pfxlen is not
specified in the input.

int
inet_cidr_ntop(ag, src, len, bits, dst, size)

this would work very much the same as inet_net_ntop() except that the
size (in octets) of src's mantissa would be given in the new "len" argument
and not imputed from "bits" as occurs now. "bits" would just be output
as the "/NN" at the end of the string, and would never be optional.

if this is agreeable, i'll code it up and submit it here for testing before
i push it out in bind 8.1.3. i really do agree with the functionality we've
drifted toward in this type -- if folks want to express the netmask of a
host address without getting in trouble for a nonzero host part that's
lost during parsing and storage, then they jolly well ought to be able to
do that.

In reply to: Paul A Vixie (#5)
Re: [HACKERS] Re: inet/cidr/bind

Paul A Vixie <paul@vix.com> writes:

if this is agreeable, i'll code it up and submit it here for testing
before i push it out in bind 8.1.3. i really do agree with the
functionality we've drifted toward in this type -- if folks want to
express the netmask of a host address without getting in trouble for
a nonzero host part that's lost during parsing and storage, then
they jolly well ought to be able to do that.

I certainly agree. We should then be able to switch very easily and
cleanly to the use of these new input and output functions, and add
the various utility functions that D'Arcy has outlined. Should be
quick work.

We should leave the type name as INET, I think.

Bruce/Marc: we're OK for 6.4 with this still, right? Even if it takes
a couple more days to get everything to fall into place?

-tih
--
Popularity is the hallmark of mediocrity. --Niles Crane, "Frasier"

#7Bruce Momjian
maillist@candle.pha.pa.us
In reply to: Tom Ivar Helbekkmo (#6)
Re: [HACKERS] Re: inet/cidr/bind

Paul A Vixie <paul@vix.com> writes:

if this is agreeable, i'll code it up and submit it here for testing
before i push it out in bind 8.1.3. i really do agree with the
functionality we've drifted toward in this type -- if folks want to
express the netmask of a host address without getting in trouble for
a nonzero host part that's lost during parsing and storage, then
they jolly well ought to be able to do that.

I certainly agree. We should then be able to switch very easily and
cleanly to the use of these new input and output functions, and add
the various utility functions that D'Arcy has outlined. Should be
quick work.

We should leave the type name as INET, I think.

Bruce/Marc: we're OK for 6.4 with this still, right? Even if it takes
a couple more days to get everything to fall into place?

I think so. It does not affect people testing other things.

-- 
  Bruce Momjian                        |  http://www.op.net/~candle
  maillist@candle.pha.pa.us            |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#8Noname
darcy@druid.net
In reply to: Tom Ivar Helbekkmo (#6)
Re: [HACKERS] Re: inet/cidr/bind

Thus spake Tom Ivar Helbekkmo

if this is agreeable, i'll code it up and submit it here for testing
before i push it out in bind 8.1.3. i really do agree with the
functionality we've drifted toward in this type -- if folks want to
express the netmask of a host address without getting in trouble for
a nonzero host part that's lost during parsing and storage, then
they jolly well ought to be able to do that.

OK, I have cobbled up some functions and modified others in inet.c
based on the suggested cidr utility functions. I have made a few
assumptions which I am sure we will have to look at so that everyone
is comfortable with the code. I have added the following new functions.

char *inet_netmask(inet * addr);
int4 inet_masklen(inet * addr);
char *inet_host(inet * addr);
char *inet_network_no_bits(inet * addr);
char *inet_network_and_bits(inet * addr);
char *inet_broadcast(inet * addr);

The difference between inet_network_no_bits and inet_network_and_bits is
that for a.b.c.d/24, the former will return a.b.c and the latter will
return a.b.c/24. I couldn't use inet_network as a name anyway since
it conflicts with something in arpa/inet.h (On NetBSD -current).

If someone will add the necessary entries to the catalogues, I'll
start testing them. I'll post the changes to inet.c and builtins.h
to the patches list. I can't guarantee that they are bug-free yet
but it does compile and shouldn't interfere with anything anyone
else is doing.

-- 
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 424 2871     (DoD#0082)    (eNTP)   |  what's for dinner.
In reply to: Noname (#8)
Re: [HACKERS] Re: inet/cidr/bind

darcy@druid.net (D'Arcy J.M. Cain) writes:

I have another question. What is the point of "used?" Can't I just
assume 4 octets for ipv4 and 6 for ipv6? Can I set it to NULL if I
don't care about the value?

Not an answer to your question, but IPV6 does not use 6 byte
addresses; they are 16 bytes long.

-tih
--
Popularity is the hallmark of mediocrity. --Niles Crane, "Frasier"

#10Paul A Vixie
paul@vix.com
In reply to: Tom Ivar Helbekkmo (#9)
Re: inet/cidr/bind

From: darcy@druid.net (D'Arcy J.M. Cain)
Date: Sun, 11 Oct 1998 07:17:58 -0400 (EDT)

Thus spake Paul A Vixie

int
inet_cidr_pton(af, src, dst, size, int *used)

this would work very much the same as inet_net_pton() except for three
things: (1) nonzero trailing mantissas (host parts) would be allowed; (2)
the number of consumed octets of dst would be set into *used; and (3) there
would be absolutely no classful assumptions made if the pfxlen is not
specified in the input.

Is there also agreement on the use of -1 to mean unspecified netmask?

ok. this means we have to return octets and use an argument for *bits.

How about the optional input form h.h.h.h:m.m.m.m to specify netmask?

i'd rather avoid this, since cidr does not allow noncontiguous netmasks
and i'd rather not create another error return case unless it's REALLY
important. is it? as currently specified:

/*
* static int
* inet_cidr_pton(af, src, dst, size, *bits)
* convert network address from presentation to network format.
* accepts hex octets, hex strings, decimal octets, and /CIDR.
* "size" is in bytes and describes "dst". "bits" is set to the
* /CIDR prefix length if one was specified, or -1 otherwise.
* return:
* number of octets consumed of "dst", or -1 if some failure occurred
* (check errno). ENOENT means it was not a valid network address.
* note:
* 192.5.5.1/28 has a nonzero host part, which means it isn't a network
* as called for by inet_net_pton() but it can be a host address with
* an included netmask.
* author:
* Paul Vixie (ISC), October 1998
*/
int
inet_net_pton(int af, const char *src,
void *dst, size_t size,
int *bits)
{
switch (af) {
case AF_INET:
return (inet_cidr_pton_ipv4(src, dst, size, bits));
default:
errno = EAFNOSUPPORT;
return (-1);
}
}

int
inet_cidr_ntop(ag, src, len, bits, dst, size)

this would work very much the same as inet_net_ntop() except that the
size (in octets) of src's mantissa would be given in the new "len" argument
and not imputed from "bits" as occurs now. "bits" would just be output
as the "/NN" at the end of the string, and would never be optional.

And if bits is -1 then don't print the /NN part, right?

ok. here's what that looks like, for comments before i write it:

/*
* char *
* inet_cidr_ntop(af, src, len, bits, dst, size)
* convert network address from network to presentation format.
* generates "/CIDR" style result unless "bits" is -1.
* return:
* pointer to dst, or NULL if an error occurred (check errno).
* note:
* 192.5.5.1/28 has a nonzero host part, which means it isn't a network
* as called for by inet_net_pton() but it can be a host address with
* an included netmask.
* author:
* Paul Vixie (ISC), October 1998
*/
char *
inet_cidr_ntop(int af, const void *src, size_t len, int bits,
char *dst, size_t size)
{
switch (af) {
case AF_INET:
return (inet_cidr_ntop_ipv4(src, len, bits, dst, size));
default:
errno = EAFNOSUPPORT;
return (NULL);
}
}

From: darcy@druid.net (D'Arcy J.M. Cain)
Date: Sun, 11 Oct 1998 07:40:41 -0400 (EDT)

Thus spake Paul A Vixie

int
inet_cidr_pton(af, src, dst, size, int *used)

this would work very much the same as inet_net_pton() except for three
things: (1) nonzero trailing mantissas (host parts) would be allowed; (2)
the number of consumed octets of dst would be set into *used; and (3) there
would be absolutely no classful assumptions made if the pfxlen is not
specified in the input.

I have another question. What is the point of "used?" Can't I just
assume 4 octets for ipv4 and 6 for ipv6? Can I set it to NULL if I
don't care about the value?

we probably could have done this until we had to return octets and fill *used
with the bits. but more importantly, i think we should still only touch the
octets in *dst that are nec'y. this is consistent with the _ntop() as well.

From: darcy@druid.net (D'Arcy J.M. Cain)
Date: Sun, 11 Oct 1998 20:22:25 -0400 (EDT)

... [One] more thing. I built my stuff on the assumption that the
inet_cidr_ntop function returned char *, not int. I assume that was
just an error in your message. In fact, here is the way I added the
prototypes to builtins.h.

Yes.

char *inet_cidr_ntop(int af, const void *src, size_t len, int bits, char *dst, size_t size);
int inet_cidr_pton(int af, const void *src, void *dst, size_t size, int *used);

Is this what you had in mind?

Yes. But note that as now proposed, inet_cidr_pton() returns octets not bits
as earlier proposed, and sets *used to the bits not the octets as earlier
proposed.

If there are no further comments?

(In case y'all are wondering, this is how BIND's other library functions
got specified, though the driving application wasn't PostGreSQL last time.)

#11Noname
darcy@druid.net
In reply to: Paul A Vixie (#10)
Re: [HACKERS] Re: inet/cidr/bind

Thus spake Paul A Vixie

From: darcy@druid.net (D'Arcy J.M. Cain)
How about the optional input form h.h.h.h:m.m.m.m to specify netmask?

i'd rather avoid this, since cidr does not allow noncontiguous netmasks
and i'd rather not create another error return case unless it's REALLY
important. is it? as currently specified:

Not that important I think. It was just a leftover though from earlier
discussions. I just wanted to make sure we considered it. The issue
of the extra error return came up back then too.

/*
* static int
* inet_cidr_pton(af, src, dst, size, *bits)
* convert network address from presentation to network format.
* accepts hex octets, hex strings, decimal octets, and /CIDR.
* "size" is in bytes and describes "dst". "bits" is set to the
* /CIDR prefix length if one was specified, or -1 otherwise.
* return:
* number of octets consumed of "dst", or -1 if some failure occurred
* (check errno). ENOENT means it was not a valid network address.

So if it is a network we don't have to fill the whole structure, right?
What happens on these calls?

inet_cidr_pton(af, "192.5/16", dst, sizeof dst, &bits);
inet_cidr_pton(af, "192.5/24", dst, sizeof dst, &bits);
inet_cidr_pton(af, "192.5.5.1/16", dst, sizeof dst, &bits);

I'm guessing that the return and bits for each would be (2, 16), (3, 24)
and (4, 16). Is that correct or since they are all ipv4 addresses would
the size always be 4?

* note:
* 192.5.5.1/28 has a nonzero host part, which means it isn't a network
* as called for by inet_net_pton() but it can be a host address with
* an included netmask.
* author:
* Paul Vixie (ISC), October 1998
*/
int
inet_net_pton(int af, const char *src,

inet_cidr_pton?

ok. here's what that looks like, for comments before i write it:

/*
* char *
* inet_cidr_ntop(af, src, len, bits, dst, size)
* convert network address from network to presentation format.
* generates "/CIDR" style result unless "bits" is -1.

Sounds right.

I have another question. What is the point of "used?" Can't I just
assume 4 octets for ipv4 and 6 for ipv6? Can I set it to NULL if I
don't care about the value?

we probably could have done this until we had to return octets and fill *used
with the bits. but more importantly, i think we should still only touch the
octets in *dst that are nec'y. this is consistent with the _ntop() as well.

Does this mean we need to add a size element to the inet structure?

Yes. But note that as now proposed, inet_cidr_pton() returns octets not bits
as earlier proposed, and sets *used to the bits not the octets as earlier
proposed.

OK. I'll wait till your stuff has been added to fix my stuff. That way
I can test it and send in the final changes once (hopefully.)

-- 
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 424 2871     (DoD#0082)    (eNTP)   |  what's for dinner.
#12Paul A Vixie
paul@vix.com
In reply to: Noname (#11)
Re: [HACKERS] Re: inet/cidr/bind

So if it is a network we don't have to fill the whole structure, right?

right.

What happens on these calls?

inet_cidr_pton(af, "192.5/16", dst, sizeof dst, &bits);
inet_cidr_pton(af, "192.5/24", dst, sizeof dst, &bits);
inet_cidr_pton(af, "192.5.5.1/16", dst, sizeof dst, &bits);

I'm guessing that the return and bits for each would be (2, 16), (3, 24)
and (4, 16). Is that correct or since they are all ipv4 addresses would
the size always be 4?

yes. :-). i mean, the former. {2,16}, {3,24}, and {4,16}. ipv4 is the
family of the address but does not dictate the size of the prefix. i still
don't want to touch octets which aren't specified, any more than i would
want to emit them in _ntop(). but that's my preference speaking -- what is
yours?

int
inet_net_pton(int af, const char *src,

inet_cidr_pton?

oops, yeah. you can see where i copied this stuff from.

Does this mean we need to add a size element to the inet structure?

i think so, yes.

#13Noname
darcy@druid.net
In reply to: Paul A Vixie (#12)
Re: [HACKERS] Re: inet/cidr/bind

Thus spake Paul A Vixie

inet_cidr_pton(af, "192.5/16", dst, sizeof dst, &bits);
inet_cidr_pton(af, "192.5/24", dst, sizeof dst, &bits);
inet_cidr_pton(af, "192.5.5.1/16", dst, sizeof dst, &bits);

I'm guessing that the return and bits for each would be (2, 16), (3, 24)
and (4, 16). Is that correct or since they are all ipv4 addresses would
the size always be 4?

yes. :-). i mean, the former. {2,16}, {3,24}, and {4,16}. ipv4 is the
family of the address but does not dictate the size of the prefix. i still
don't want to touch octets which aren't specified, any more than i would
want to emit them in _ntop(). but that's my preference speaking -- what is
yours?

Well, I don't mind filling in the whole structure. It would simplify
a few things and we wouldn't need to add a size element to the structure.
The network function will output it correctly, I think.

inet_network_with_bits('192.5/16') => '192.5/16'
inet_network_with_bits('192.5.5.1/16') => '192.5/16'
inet_network_with_bits('192.5/24') => '192.5.0/16'

Does this seem right?

Does this mean we need to add a size element to the inet structure?

i think so, yes.

Unless we zero-pad, right?

-- 
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 424 2871     (DoD#0082)    (eNTP)   |  what's for dinner.
#14Paul A Vixie
paul@vix.com
In reply to: Noname (#13)
Re: [HACKERS] Re: inet/cidr/bind

From: darcy@druid.net (D'Arcy J.M. Cain)
Date: Tue, 13 Oct 1998 12:58:03 -0400 (EDT)

Well, I don't mind filling in the whole structure. It would simplify
a few things and we wouldn't need to add a size element to the structure.

ok.

The network function will output it correctly, I think.

inet_network_with_bits('192.5/16') => '192.5/16'
inet_network_with_bits('192.5.5.1/16') => '192.5/16'
inet_network_with_bits('192.5/24') => '192.5.0/16'

Does this seem right?

for networks, yes.

Does this mean we need to add a size element to the inet structure?

i think so, yes.

Unless we zero-pad, right?

ok. here's the current proposal. any further comments?

/*
* char *
* inet_cidr_ntop(af, src, bits, dst, size)
* convert network address from network to presentation format.
* generates "/CIDR" style result unless "bits" is -1. "src"'s
* size is determined from its "af".
* return:
* pointer to dst, or NULL if an error occurred (check errno).
* note:
* 192.5.5.1/28 has a nonzero host part, which means it isn't a network
* as called for by inet_net_pton() but it can be a host address with
* an included netmask.
* author:
* Paul Vixie (ISC), October 1998
*/
char *
inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size) {
switch (af) {
case AF_INET:
return (inet_cidr_ntop_ipv4(src, bits, dst, size));
default:
errno = EAFNOSUPPORT;
return (NULL);
}
}

...

/*
* int
* inet_cidr_pton(af, src, dst, *bits)
* convert network address from presentation to network format.
* accepts hex octets, hex strings, decimal octets, and /CIDR.
* "dst" is assumed large enough for its "af". "bits" is set to the
* /CIDR prefix length if one was specified, or -1 otherwise.
* return:
* 0 on success, or -1 if some failure occurred (check errno).
* ENOENT means it was not a valid network address.
* note:
* 192.5.5.1/28 has a nonzero host part, which means it isn't a network
* as called for by inet_net_pton() but it can be a host address with
* an included netmask.
* author:
* Paul Vixie (ISC), October 1998
*/
int
inet_cidr_pton(int af, const char *src, void *dst, int *bits) {
switch (af) {
case AF_INET:
return (inet_cidr_pton_ipv4(src, dst, bits));
default:
errno = EAFNOSUPPORT;
return (-1);
}
}

#15Noname
darcy@druid.net
In reply to: Paul A Vixie (#14)
Re: [HACKERS] Re: inet/cidr/bind

Thus spake Paul A Vixie

The network function will output it correctly, I think.

inet_network_with_bits('192.5/16') => '192.5/16'
inet_network_with_bits('192.5.5.1/16') => '192.5/16'
inet_network_with_bits('192.5/24') => '192.5.0/16'

Does this seem right?

for networks, yes.

Hmm. It _is_ the network function I was talking about. The same inputs
whould give the following results.

Input Network (with) Network (without) Host Broadcast
192.5/16 192.5/16 192.5 192.5.0.0 192.5.255.255
192.5.5.1/16 192.5/16 192.5 192.5.0.0 192.5.255.255
192.5/24 192.5.0/16 192.5.0 192.5.0.0 192.5.0.255

Of course, you wouldn't expect the first and last to have the host function
applied to it. They are probably in a field used to store networks.

ok. here's the current proposal. any further comments?

/*
* char *
* inet_cidr_ntop(af, src, bits, dst, size)
* convert network address from network to presentation format.
* generates "/CIDR" style result unless "bits" is -1. "src"'s
* size is determined from its "af".

And size is the available space in dst, right? Perfect.

/*
* int
* inet_cidr_pton(af, src, dst, *bits)
* convert network address from presentation to network format.
* accepts hex octets, hex strings, decimal octets, and /CIDR.
* "dst" is assumed large enough for its "af". "bits" is set to the
* /CIDR prefix length if one was specified, or -1 otherwise.

This sounds bang-on to me. How soon before your functions are in the
tree? I'll start modifying my code based on this but I won't send it
in until I have tested it against your functions.

By George! I think we've got it. :-)

-- 
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 424 2871     (DoD#0082)    (eNTP)   |  what's for dinner.
#16Bruce Momjian
maillist@candle.pha.pa.us
In reply to: Noname (#15)
Re: [HACKERS] Re: inet/cidr/bind

This sounds bang-on to me. How soon before your functions are in the
tree? I'll start modifying my code based on this but I won't send it
in until I have tested it against your functions.

I have not seen any patch yet. Paul, was your earlier posting supposed
to be applied? If so, let me know.

-- 
  Bruce Momjian                        |  http://www.op.net/~candle
  maillist@candle.pha.pa.us            |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
In reply to: Noname (#15)
Re: [HACKERS] Re: inet/cidr/bind

darcy@druid.net (D'Arcy J.M. Cain) writes:

By George! I think we've got it. :-)

Yup! Great work, guys! I like what I see in the tree so far -- just
waiting for the transition to complete so I can use my network data
again! :-)

-tih
--
Popularity is the hallmark of mediocrity. --Niles Crane, "Frasier"

#18Paul A Vixie
paul@vix.com
In reply to: Bruce Momjian (#16)
Re: [HACKERS] Re: inet/cidr/bind

This sounds bang-on to me. How soon before your functions are in the
tree? I'll start modifying my code based on this but I won't send it
in until I have tested it against your functions.

I have not seen any patch yet. Paul, was your earlier posting supposed
to be applied? If so, let me know.

no. i will supply new source files to replace and augment the bind-based
source files in your current pool. (i'll want the new $Id:$'s for example.)

#19Thomas G. Lockhart
lockhart@alumni.caltech.edu
In reply to: Noname (#15)
Re: [HACKERS] Re: inet/cidr/bind

By George! I think we've got it. :-)

Yup! Great work, guys! I like what I see in the tree so far -- just
waiting for the transition to complete so I can use my network data
again! :-)

I've forgotten who volunteered to write or update docs for this. I need
to freeze the User's Guide fairly soon (~4 days?), and need to add a
mention of the CIDR data type in "datatype.sgml".

I assume that the README.inet which is currently in the tree is not an
accurate document now? I would be happy to transcribe a plain text
description into sgml, and would then expect last-minute updates to
happen in the sgml source rather than the original plain text. OK?

- Tom

#20Bruce Momjian
maillist@candle.pha.pa.us
In reply to: Thomas G. Lockhart (#19)
Re: [HACKERS] Re: inet/cidr/bind

By George! I think we've got it. :-)

Yup! Great work, guys! I like what I see in the tree so far -- just
waiting for the transition to complete so I can use my network data
again! :-)

I've forgotten who volunteered to write or update docs for this. I need
to freeze the User's Guide fairly soon (~4 days?), and need to add a
mention of the CIDR data type in "datatype.sgml".

I assume that the README.inet which is currently in the tree is not an
accurate document now? I would be happy to transcribe a plain text
description into sgml, and would then expect last-minute updates to
happen in the sgml source rather than the original plain text. OK?

There were no volunteers, and in fact, it is still changing. When it is
done, one of the few people who have followed the features will have to
write something up.

-- 
  Bruce Momjian                        |  http://www.op.net/~candle
  maillist@candle.pha.pa.us            |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#21Noname
darcy@druid.net
In reply to: Bruce Momjian (#20)
Re: [HACKERS] Re: inet/cidr/bind

Thus spake Paul A Vixie

if someone wants to be able to represent a host address and a netmask,
then may i suggest that they use the same type, except they'll have to
use two of them, one for the host address and one for the netmask. in
this case the prefix length would like to be enforced/implied at /32,
and never printed. this is not a CIDR. it's how BIND's "inet_ntop"
and "inet_pton" work.

If you are forcing/implying the netmask in the host type, why not just use
it for the netmask? The point of my functions is to extract the different
parts from that.

if someone wants to be able to represent a CIDRized host address, that
is, a host and prefix, which means the host-part "can be" zero or non-zero,
and the prefix might or might not be required in input or printed in output,
then that's an entirely different thing from either of the above. and
while i've got the code almost ready to do that, i don't want this behaviour
in my own target application for the original "cidr" prototype i sent in.

it looks to me as though we've got three new pgsql types here. you agree?

As far as I understand, that last is the only one we were expecting in
PostgreSQL. So how about this? Let's put back all of the original inet
stuff but call it cidr. Finish your stuff and we'll put it in as the
inet type. Personally I think we just need the latter but I would
rather have both than neither.

I just noticed that this wasn't copied to the list. I hope you don't
mind me copying this response there so that others can add their
opinions too.

-- 
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 424 2871     (DoD#0082)    (eNTP)   |  what's for dinner.
#22Paul A Vixie
paul@vix.com
In reply to: Noname (#21)
Re: [HACKERS] Re: inet/cidr/bind

If you are forcing/implying the netmask in the host type, why not just use
it for the netmask? The point of my functions is to extract the different
parts from that.

Functions to extract it is one thing. What the data type can contain is
another. I'm building a registry database of CIDRized IP delegations and
I need it to be an error to insert an element whose host-part is nonzero.
That was the launch application for the original "cidr" type I contributed,
and in the resulting hullabaloo we ended up trying to represent "hosts"
which had potential nonzero content across all 32 bits even though the
netmask was less than 32 bits long. I can't make any good use of that in
my application.

Again, the question of whether there are functions available to build up
or tear apart these compound values is not relevant to my point here. It's
a good idea to have such functions if the type is constructed as has been
proposed here during the recent hullabaloo.

But in my application, I need to be able to key a table to a network block,
and it is literally meaningless to have a nonzero host part or a fixed size
mantissa in that application.

Since other people want to use this type differently, I propose that we make
it into two types: INET for host addresses and CIDR for network addresses.
Both can include /## to set a netmask if folks really don't like making the
address and netmask into two adjacent columns. But CIDR has to disallow
nonzero host-parts or it doesn't mean what I need it to mean.

PostgreSQL has an opportunity here to be the first SQL system to be able to
natively support IP registries. There's some market share lurking in this.

if someone wants to be able to represent a CIDRized host address, that
is, a host and prefix, which means the host-part "can be" zero or non-zero,
and the prefix might or might not be required in input or printed in output
then that's an entirely different thing from either of the above. and while
i've got the code almost ready to do that, i don't want this behaviour
in my own target application for the original "cidr" prototype i sent in.

it looks to me as though we've got three new pgsql types here. you agree?

As far as I understand, that last is the only one we were expecting in
PostgreSQL. So how about this? Let's put back all of the original inet
stuff but call it cidr. Finish your stuff and we'll put it in as the
inet type. Personally I think we just need the latter but I would
rather have both than neither.

Ok. Will you take care of integrating both types, including indexing? (My
inability to use the original cidr type for an index was my original problem.)

I just noticed that this wasn't copied to the list. I hope you don't
mind me copying this response there so that others can add their
opinions too.

Actually I do mind, and had I been addressing the larger audience my note
would have been a lot clearer. But now that we've moved the discussion here
I'm CC'ing the list on my response as well. No harm done.

#23Noname
darcy@druid.net
In reply to: Paul A Vixie (#22)
Re: [HACKERS] Re: inet/cidr/bind

Thus spake Paul A Vixie

Since other people want to use this type differently, I propose that we make
it into two types: INET for host addresses and CIDR for network addresses.
Both can include /## to set a netmask if folks really don't like making the
address and netmask into two adjacent columns. But CIDR has to disallow
nonzero host-parts or it doesn't mean what I need it to mean.

I am cool with this. In fact I think I mentioned earlier in the thread that
this requirement (it was a theoretical possibility to me at the time) was
the one reason why two different types might be required. OK so that
means that, as I suggested, we need two underlying function sets, the
inet_net_* ones and the inet_cidr_* ones (might be some efficiency
possible if they are in the same source file and use some common
routines) and the original inet.c file gets changed to cidr.c and
turned into the cidr type. I'll take the existing inet.c as it exists
on my system and submit it as the _new_ inet type.

Of course we can both use the same structure to store the data. I suggest
we leave the name as inet since cidr seems to be a special case of inet.
Do you agree?

Ok. Will you take care of integrating both types, including indexing? (My
inability to use the original cidr type for an index was my original problem.)

If you mean adding to the catalogues I believe Bruce is dealing with that.
I will make a new cidr.c file which is basically the original one with
a few replacements for the new names. Will you have the final inet_net_*
and inet_cidr_* functions in the tree shortly?

I just noticed that this wasn't copied to the list. I hope you don't
mind me copying this response there so that others can add their
opinions too.

Actually I do mind, and had I been addressing the larger audience my note
would have been a lot clearer. But now that we've moved the discussion here
I'm CC'ing the list on my response as well. No harm done.

Oops. Sorry about that. I thought that you simply forgot to copy
the list. Anyway, there are a few people with fingers in this
particular pie so it's probably just as well. This is the hackers
list so I don't imagine many people found your message unclear. I
certainly didn't.

-- 
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 424 2871     (DoD#0082)    (eNTP)   |  what's for dinner.
#24Bruce Momjian
maillist@candle.pha.pa.us
In reply to: Noname (#23)
Re: [HACKERS] Re: inet/cidr/bind

Thus spake Paul A Vixie

Since other people want to use this type differently, I propose that we make
it into two types: INET for host addresses and CIDR for network addresses.
Both can include /## to set a netmask if folks really don't like making the
address and netmask into two adjacent columns. But CIDR has to disallow
nonzero host-parts or it doesn't mean what I need it to mean.

I am cool with this. In fact I think I mentioned earlier in the thread that
this requirement (it was a theoretical possibility to me at the time) was
the one reason why two different types might be required. OK so that
means that, as I suggested, we need two underlying function sets, the
inet_net_* ones and the inet_cidr_* ones (might be some efficiency
possible if they are in the same source file and use some common
routines) and the original inet.c file gets changed to cidr.c and
turned into the cidr type. I'll take the existing inet.c as it exists
on my system and submit it as the _new_ inet type.

Sorry, but I just have to ask. I am not sure what the issues are, but
it is possible to have them all be the same type. Have a netmask field
inside the type and a cidr field inside the type, and just use one of
them at a time for any given entry? Only one byte each, right? I sure
would like to avoid "type/function bloat". Also, could a RULE be
created to simulate the network restriction Paul requires?

Maybe it is clearer to have two types, with different purposes. I am
just asking, and if people are going to need functions to convert
between the two types, it may be worth merging them. I was thinking you
could display them differently based on which field they used.

This is all just a guess.

-- 
  Bruce Momjian                        |  http://www.op.net/~candle
  maillist@candle.pha.pa.us            |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#25Bruce Momjian
maillist@candle.pha.pa.us
In reply to: Bruce Momjian (#24)
Re: [HACKERS] Re: inet/cidr/bind

Thus spake Paul A Vixie

Since other people want to use this type differently, I propose that we make
it into two types: INET for host addresses and CIDR for network addresses.
Both can include /## to set a netmask if folks really don't like making the
address and netmask into two adjacent columns. But CIDR has to disallow
nonzero host-parts or it doesn't mean what I need it to mean.

Paul, can you give the unknowledgable among us an example of what you
want and don't want? Thanks.

I was assuming the type would allow these as hosts:

192.4.13.42
192.4.13.42 255.255.255.0
192.4.13.42/32
192.4.13.42/32 255.255.255.0

and these are networks:

192.63.91.234/28
192.63.91.234/28 255.255.255.128

Any non-32 '/' is a network? Can a network have a netmask? Not sure.
Internally, a -1 in a field indicates the user did not supply a cidr
value(assume it is a host), or did not specify a netmask. I thought
this is where D'Arcy was going with this.

I assume we are _not_ going to use the /24 notation to specify a
netmask, because the cidr '/' notation has never been used for that,
right?

I am cool with this. In fact I think I mentioned earlier in the thread that
this requirement (it was a theoretical possibility to me at the time) was
the one reason why two different types might be required. OK so that
means that, as I suggested, we need two underlying function sets, the
inet_net_* ones and the inet_cidr_* ones (might be some efficiency
possible if they are in the same source file and use some common
routines) and the original inet.c file gets changed to cidr.c and
turned into the cidr type. I'll take the existing inet.c as it exists
on my system and submit it as the _new_ inet type.

Sorry, but I just have to ask. I am not sure what the issues are, but
it is possible to have them all be the same type. Have a netmask field
inside the type and a cidr field inside the type, and just use one of
them at a time for any given entry? Only one byte each, right? I sure
would like to avoid "type/function bloat". Also, could a RULE be
created to simulate the network restriction Paul requires?

Maybe it is clearer to have two types, with different purposes. I am
just asking, and if people are going to need functions to convert
between the two types, it may be worth merging them. I was thinking you
could display them differently based on which field they used.

This is all just a guess.

If I am wrong about the above, I have one more question. Would an
atttypmod setting for each column help? What about a compile-time
define?

I know Paul is a big name, but are the duplicate types meaningful for
ordinary users, or would they prefer just one type. If they would
prefer one type, we can do that, and make sure Paul gets what he wants
too.

Want something really fancy?

CREATE TABLE hostnet(
host inet(host),
network inet(net),
misc inet
);

This is possible.

If we can get some more rapid-fire e-mails going around, I think we can
resolve this in the next day or two. We have testing and documenation
to do, and Marc at some point may pull the plug on us.

I am ready to install whatever you folks come up with.

If we can come up with one type, that is less bloat/work for me, but my
primary goal is that we come up with a solid type/types that we aren't
going to need to redesign in the future, causing problems for existing
users.

-- 
  Bruce Momjian                        |  http://www.op.net/~candle
  maillist@candle.pha.pa.us            |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#26Noname
darcy@druid.net
In reply to: Bruce Momjian (#24)
Re: [HACKERS] Re: inet/cidr/bind

Thus spake Bruce Momjian

Sorry, but I just have to ask. I am not sure what the issues are, but
it is possible to have them all be the same type. Have a netmask field
inside the type and a cidr field inside the type, and just use one of
them at a time for any given entry? Only one byte each, right? I sure
would like to avoid "type/function bloat". Also, could a RULE be
created to simulate the network restriction Paul requires?

Maybe it is clearer to have two types, with different purposes. I am
just asking, and if people are going to need functions to convert
between the two types, it may be worth merging them. I was thinking you
could display them differently based on which field they used.

I can think of two possibilities. I thought of this before for other
purposes but I never asked about it. Can we set up inet_in to take
a second argument? If so then we can set up two types but set them
up such that one calls the in function with 0 and one with 1. We
would store that value in a new field in the structure and check
that for every other function where necessary.

If not then we can do the same thing by creating two wrapper input
functions which call the one I have described with the extra argument.
Almost as good.

If this makes sense I suggest we go forward with our existing plan and
look to fold it after 6.4. It's minor bloat for now and it would
simplify getting everything in there.

-- 
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 424 2871     (DoD#0082)    (eNTP)   |  what's for dinner.
#27Noname
darcy@druid.net
In reply to: Bruce Momjian (#25)
Re: [HACKERS] Re: inet/cidr/bind

Thus spake Bruce Momjian

Paul, can you give the unknowledgable among us an example of what you
want and don't want? Thanks.

Let me take a stab at it too.

I was assuming the type would allow these as hosts:

192.4.13.42
192.4.13.42 255.255.255.0

An alternate syntax of 192.4.13.42:255.255.255.0 was proposed but won't
be implemented, at least at this time. Maybe put it into TODO for 6.4++.
In the meantime, this should be 192.4.13.42/24.

192.4.13.42/32
192.4.13.42/32 255.255.255.0

Basically two different netmasks. I think you mean 192.4.13.42/24 here too.

and these are networks:

192.63.91.234/28

This is a host in a 16 IP subnet. As a cidr type (as proposed) this
would be invalid. Note the 234 is 11101010b and the /28 implies a
trailing octet of 11110000b. A valid entry would have been something
like 192.63.91.224/28.

192.63.91.234/28 255.255.255.128

Again, the /28 and the 255.255.255.128 are trying to specify the same
thing but they are different. The /28 is an alternate way of saying
a netmask of 255.255.255.240. 255.255.255.128 would be /25. Either
way, this is invalid as a cidr but valid as an inet host on a network.

Any non-32 '/' is a network? Can a network have a netmask? Not sure.

Nope. /32 is a valid network. It's a class D in the old class system.
That's why I suggested -1 for an unspecified netmask to differentiate
it from a network of one host.

A network can certainly have a netmask. In fact, it always does. It
can be implied in certain cases. The following (if I understand Paul's
proposal - correct me if not) show the relationships.

Input cidr output inet output
============= ================ ================
192.63.91.234 192.63.91.234/32 192.63.91.234/32
192.63.91 192.63.91/24 192.63.91.0/24
192.63 192.63/16 192.63.0.0/16
192 192/8 192.0.0.0/8

This look right to you, Paul?

Internally, a -1 in a field indicates the user did not supply a cidr
value(assume it is a host), or did not specify a netmask. I thought
this is where D'Arcy was going with this.

Close. A -1 is only valid for the inet type, not the cidr type. This
is because the /XX effectively specifies both the network and netmask.
Under cidr this must be specified. Under inet it may be. If it isn't,
or -1 is specified, -1 is stored as the bits and it is not output on
display. This allows it to be used as a host or as a host/network
combination. Note that there is nothing stopping you from using the
inet type to store networks too. It's just that using cidr does the
extra error checking and outputs in the more standard network format.

I assume we are _not_ going to use the /24 notation to specify a
netmask, because the cidr '/' notation has never been used for that,
right?

Well, it can be implied but I think it is OK to specify. 192.63.91 and
192.63.91/24 should be the same thing. If the number of bits is not
32, 24, 16 or 8 you have to specify it.

If I am wrong about the above, I have one more question. Would an
atttypmod setting for each column help? What about a compile-time
define?

We discussed this at one point. I think that is more useful for
specifying output formats. For example, 192.63.91.234/24 is identical
to 192.63.91.234:255.255.255.0 (if we add that format) but I think
that's 6.4++ too. I think it would also only apply to the inet type
but Paul should know.

I know Paul is a big name, but are the duplicate types meaningful for
ordinary users, or would they prefer just one type. If they would
prefer one type, we can do that, and make sure Paul gets what he wants
too.

I understand why Paul needs his type but I think the inet type is
valuable too. I think my suggestion above is a good compromise.

If we can get some more rapid-fire e-mails going around, I think we can
resolve this in the next day or two. We have testing and documenation
to do, and Marc at some point may pull the plug on us.

If we can come up with one type, that is less bloat/work for me, but my
primary goal is that we come up with a solid type/types that we aren't
going to need to redesign in the future, causing problems for existing
users.

I think we are just about there. If we go with my plan (completely
different functionality for now and fold it later) there should be
no API change later. There will be code and catalogue changes but
they should be relatively painless.

-- 
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 424 2871     (DoD#0082)    (eNTP)   |  what's for dinner.
#28Paul A Vixie
paul@vix.com
In reply to: Noname (#27)
Re: [HACKERS] Re: inet/cidr/bind

A network can certainly have a netmask. In fact, it always does. It
can be implied in certain cases. The following (if I understand Paul's
proposal - correct me if not) show the relationships.

Input cidr output inet output
============= ================ ================
192.63.91.234 192.63.91.234/32 192.63.91.234/32
192.63.91 192.63.91/24 192.63.91.0/24
192.63 192.63/16 192.63.0.0/16
192 192/8 192.0.0.0/8

This look right to you, Paul?

no. the last three inputs are not valid where a host address is expected.

If I am wrong about the above, I have one more question. Would an
atttypmod setting for each column help? What about a compile-time
define?

We discussed this at one point. I think that is more useful for
specifying output formats. For example, 192.63.91.234/24 is identical
to 192.63.91.234:255.255.255.0 (if we add that format) but I think
that's 6.4++ too. I think it would also only apply to the inet type
but Paul should know.

I know Paul is a big name, but are the duplicate types meaningful for
ordinary users, or would they prefer just one type. If they would
prefer one type, we can do that, and make sure Paul gets what he wants
too.

I understand why Paul needs his type but I think the inet type is
valuable too. I think my suggestion above is a good compromise.

bigness of names doesn't matter. applications matter. i can see a use for
both types, but they are inherently different types. a host that has a
netmask which can be expressed in cidr notation is one such type. a net
that has a netmask which must be expressed in cidr notation is another such
type. the difference comes down to "host part must be zero" for the network
type. there are also some minor differences in the input/output formats,
since a host address always has four octets on both input and output, while
a network only prints as many octets as the cidr width specifies, and these
are the only required octets on input (though extra .0's can be specified).

I think we are just about there. If we go with my plan (completely
different functionality for now and fold it later) there should be
no API change later. There will be code and catalogue changes but
they should be relatively painless.

so shall i test the inet_cidr_ functions and punt them on in?

#29Taral
taral@mail.utexas.edu
In reply to: Paul A Vixie (#28)
RE: [HACKERS] Re: inet/cidr/bind

Can't we just use a CONSTRAINT where a host address is expected? That sounds
easier than setting up two different types to me...

Taral

Show quoted text

-----Original Message-----
From: owner-pgsql-hackers@postgreSQL.org
[mailto:owner-pgsql-hackers@postgreSQL.org]On Behalf Of Paul A Vixie
Sent: Monday, October 19, 1998 2:08 PM
To: pgsql-hackers@postgreSQL.org
Subject: Re: [HACKERS] Re: inet/cidr/bind

A network can certainly have a netmask. In fact, it always does. It
can be implied in certain cases. The following (if I understand Paul's
proposal - correct me if not) show the relationships.

Input cidr output inet output
============= ================ ================
192.63.91.234 192.63.91.234/32 192.63.91.234/32
192.63.91 192.63.91/24 192.63.91.0/24
192.63 192.63/16 192.63.0.0/16
192 192/8 192.0.0.0/8

This look right to you, Paul?

no. the last three inputs are not valid where a host address is expected.

If I am wrong about the above, I have one more question. Would an
atttypmod setting for each column help? What about a compile-time
define?

We discussed this at one point. I think that is more useful for
specifying output formats. For example, 192.63.91.234/24 is identical
to 192.63.91.234:255.255.255.0 (if we add that format) but I think
that's 6.4++ too. I think it would also only apply to the inet type
but Paul should know.

I know Paul is a big name, but are the duplicate types meaningful for
ordinary users, or would they prefer just one type. If they would
prefer one type, we can do that, and make sure Paul gets what he wants
too.

I understand why Paul needs his type but I think the inet type is
valuable too. I think my suggestion above is a good compromise.

bigness of names doesn't matter. applications matter. i can see
a use for
both types, but they are inherently different types. a host that has a
netmask which can be expressed in cidr notation is one such type. a net
that has a netmask which must be expressed in cidr notation is
another such
type. the difference comes down to "host part must be zero" for
the network
type. there are also some minor differences in the input/output formats,
since a host address always has four octets on both input and
output, while
a network only prints as many octets as the cidr width specifies,
and these
are the only required octets on input (though extra .0's can be
specified).

I think we are just about there. If we go with my plan (completely
different functionality for now and fold it later) there should be
no API change later. There will be code and catalogue changes but
they should be relatively painless.

so shall i test the inet_cidr_ functions and punt them on in?

#30Noname
darcy@druid.net
In reply to: Paul A Vixie (#28)
Re: [HACKERS] Re: inet/cidr/bind

Thus spake Paul A Vixie

Input cidr output inet output
============= ================ ================
192.63.91.234 192.63.91.234/32 192.63.91.234/32
192.63.91 192.63.91/24 192.63.91.0/24
192.63 192.63/16 192.63.0.0/16
192 192/8 192.0.0.0/8

This look right to you, Paul?

no. the last three inputs are not valid where a host address is expected.

Can you amplify? Is it correct as far as cidr goes? If so, I have no
problem making it an error for the inet type. My thinking was based
on the earlier concept of having one type and accepting networks in it.
If we have the separate cidr type then I guess inet should always require
4 octets (until ipv6 anyway) and cidr should be used for networks.

How about something like 192.63.0.0/16? Should that be an error under the
inet type since it is the network? I am thinking not since technically
192.63.0.0 is a valid host under 192.63/16 although it is generally
avoided since there is still software that assumes that it is the
network or even the broadcast.

I understand why Paul needs his type but I think the inet type is
valuable too. I think my suggestion above is a good compromise.

bigness of names doesn't matter. applications matter. i can see a use for
both types, but they are inherently different types. a host that has a

I agree although I did change my mind somewhat based on these discussions.

And besides:

if (strlen("D'Arcy J.M. Cain") > strlen("Paul Vixie"))
printf("Who's the big name now? :-)\n");

And look at all that StUdLy punctuation. :-)

a network only prints as many octets as the cidr width specifies, and these
are the only required octets on input (though extra .0's can be specified).

Cool. You answered another question I had before I asked it.

I think we are just about there. If we go with my plan (completely
different functionality for now and fold it later) there should be
no API change later. There will be code and catalogue changes but
they should be relatively painless.

so shall i test the inet_cidr_ functions and punt them on in?

Ok, before I have a reality shift, the inet_cidr_ functions are simply
the original inet_net_ functions renamed, right?

I so hate it when the universe does that stuttering thing.
-- 
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 424 2871     (DoD#0082)    (eNTP)   |  what's for dinner.
#31Noname
darcy@druid.net
In reply to: Taral (#29)
Re: [HACKERS] Re: inet/cidr/bind

Thus spake Taral

Can't we just use a CONSTRAINT where a host address is expected? That sounds
easier than setting up two different types to me...

The constraint would be pretty complicated and it doesn't handle the
different output rules.

Don't worry. After things settle down we'll fold things together so
that there is two input wrapper functions and everything else will be
handled by the same functions so you won't hardly know the difference.
I too originally thought there should be one type but Paul has convinced
me otherwise.

-- 
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 424 2871     (DoD#0082)    (eNTP)   |  what's for dinner.
#32Bruce Momjian
maillist@candle.pha.pa.us
In reply to: Paul A Vixie (#28)
Re: [HACKERS] Re: inet/cidr/bind

bigness of names doesn't matter. applications matter. i can see a use for
both types, but they are inherently different types. a host that has a
netmask which can be expressed in cidr notation is one such type. a net
that has a netmask which must be expressed in cidr notation is another such
type. the difference comes down to "host part must be zero" for the network
type. there are also some minor differences in the input/output formats,
since a host address always has four octets on both input and output, while
a network only prints as many octets as the cidr width specifies, and these
are the only required octets on input (though extra .0's can be specified).

I think we are just about there. If we go with my plan (completely
different functionality for now and fold it later) there should be
no API change later. There will be code and catalogue changes but
they should be relatively painless.

so shall i test the inet_cidr_ functions and punt them on in?

Yep. Those are good points. Let's go.

-- 
  Bruce Momjian                        |  http://www.op.net/~candle
  maillist@candle.pha.pa.us            |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#33Bruce Momjian
maillist@candle.pha.pa.us
In reply to: Noname (#30)
Re: [HACKERS] Re: inet/cidr/bind

And besides:

if (strlen("D'Arcy J.M. Cain") > strlen("Paul Vixie"))
printf("Who's the big name now? :-)\n");

And look at all that StUdLy punctuation. :-)

That was funny.

I think we are just about there. If we go with my plan (completely
different functionality for now and fold it later) there should be
no API change later. There will be code and catalogue changes but
they should be relatively painless.

so shall i test the inet_cidr_ functions and punt them on in?

Ok, before I have a reality shift, the inet_cidr_ functions are simply
the original inet_net_ functions renamed, right?

I so hate it when the universe does that stuttering thing.

Just a clarification. If you have function that can be called with
either type, you can put two entries in pg_proc(or I can :-) ), and that
way the one function can take two types as parameters. Allows use to
maintain the type easier, and less bloat.

-- 
  Bruce Momjian                        |  http://www.op.net/~candle
  maillist@candle.pha.pa.us            |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#34Noname
darcy@druid.net
In reply to: Bruce Momjian (#33)
Re: [HACKERS] Re: inet/cidr/bind

Thus spake Bruce Momjian

so shall i test the inet_cidr_ functions and punt them on in?

Ok, before I have a reality shift, the inet_cidr_ functions are simply
the original inet_net_ functions renamed, right?

I so hate it when the universe does that stuttering thing.

Just a clarification. If you have function that can be called with
either type, you can put two entries in pg_proc(or I can :-) ), and that
way the one function can take two types as parameters. Allows use to
maintain the type easier, and less bloat.

My idea is to add a flag to the inet structure that specifies whether
the object is a cidr or an inet. Then every function checks that to
decide what action to perform (which might be to raise an exception,
trying to apply the host function to a cidr type for example) with
one exception, the input function. I see this as the functions to
do input.

inet *
inet_common_in(char *src, int flag);
This takes the input string and a flag that says whether a cidr or
an inet is being input. It pallocs the structure, sets the flag and
performs the conversion based the type. returns the inet pointer.

inet *
inet_net_in(char *src)
{
return inet_common_in(src, 0);
}

inet *
inet_cidr_in(char *src)
{
return inet_common_in(src, 1);
}

However, let's get the two types in right now with two separate groups
of functions and fold them after the release. It won't change the
user interface. Unless we think we can do it quickly.

In any case, maybe we can add the flag now since we figure we'll need
it later anyway.

-- 
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 424 2871     (DoD#0082)    (eNTP)   |  what's for dinner.
#35Bruce Momjian
maillist@candle.pha.pa.us
In reply to: Noname (#31)
Re: [HACKERS] Re: inet/cidr/bind

Thus spake Taral

Can't we just use a CONSTRAINT where a host address is expected? That sounds
easier than setting up two different types to me...

The constraint would be pretty complicated and it doesn't handle the
different output rules.

Don't worry. After things settle down we'll fold things together so
that there is two input wrapper functions and everything else will be
handled by the same functions so you won't hardly know the difference.
I too originally thought there should be one type but Paul has convinced
me otherwise.

If you define a fuction that can take inet or cidr type, I recommend you
define a typedef called something like "inet_or_cidr" that is the same
as inet, and use that in functions that can take either type.

You can then clearly see what functions can take either type. Also, you
will not know at the time you are called what type is really being
passed, but it may not matter, or you may be able to figure out what to
do based on the data inside the type.

Also, D'Arcy, the pressure is on. There will not be a lot of time for
debugging and redesign. I am here if you need help.

-- 
  Bruce Momjian                        |  http://www.op.net/~candle
  maillist@candle.pha.pa.us            |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#36Bruce Momjian
maillist@candle.pha.pa.us
In reply to: Noname (#34)
Re: [HACKERS] Re: inet/cidr/bind

However, let's get the two types in right now with two separate groups
of functions and fold them after the release. It won't change the
user interface. Unless we think we can do it quickly.

In any case, maybe we can add the flag now since we figure we'll need
it later anyway.

Once we put entries in the system tables, those really are not going to
change dramatically until 6.5.

Also, at this point, the least amount of code that can be added, should
be added. We already _had_(broken) an inet type, and now we are going
to be throwing a lot of duplicate code in there for a new type.

There is already concern that we are too close to the 6.4 final date to
do anything with the INET type. I am hearing that from another
developer.

I am not sure what to advise, but adding a new type is not trivial. It
is going to require an initdb by everyone, because it is going to be in
the regression test.

New type is involved, especially if I have to add unique indexing
functions and other stuff for the new type.

If people really want the INET/CIDR type for 6.4, we are going to need
tremendous effort to pull this off. That means good, clean code,
documenation, and testing, regression tests, and soon.

We can not just throw this in, and we can't expect the entire tree to
wait for a new type.

My personal opinion is that I am not ready to add a new type, and new
duplicate functions for that type, this close to final. I can add the
type, and the pg_proc/indexing pointers to link in the existing
inet functions, but full type inclusion is too much, I think.

For example, I have an inet_ops entry in pg_class. I don't want to add
an cidr_ops function that behaves exactly the same. If we can't do this
right, then we will not do it for 6.4. My experience is that dumping
partial solutions into 250k lines of code is a bad thing.

So, if people really want it, it has to be _good_. If is not that
important, it can wait.

These are my opinions, and of course, can be over-ruled.

-- 
  Bruce Momjian                        |  http://www.op.net/~candle
  maillist@candle.pha.pa.us            |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#37Noname
darcy@druid.net
In reply to: Bruce Momjian (#35)
Re: [HACKERS] Re: inet/cidr/bind

Thus spake Bruce Momjian

If you define a fuction that can take inet or cidr type, I recommend you
define a typedef called something like "inet_or_cidr" that is the same
as inet, and use that in functions that can take either type.

Perhaps. We can look at that 6.4++. For now there will be redundancy.
Afterwards we'll look at how to fold them.

passed, but it may not matter, or you may be able to figure out what to
do based on the data inside the type.

Ultimately, I think the latter.

Also, D'Arcy, the pressure is on. There will not be a lot of time for
debugging and redesign. I am here if you need help.

The minute that Paul's code is in the tree, I'm there. However, if it
helps, here is cidr.c which is just the original inet.c with substitutions.
There may be minor changes when I see Paul's functions so I won't submit it
to patches yet but if someone wants to review it early, here it is.

/*
* PostgreSQL type definitions for the CIDR type. This
* is for IP V4 CIDR notation, but prepared for V6: just
* add the necessary bits where the comments indicate.
*
* $Id$
*/

#include <sys/types.h>
#include <sys/socket.h>

#include <stdio.h>
#include <string.h>
#include <errno.h>

#include <netinet/in.h>
#include <arpa/inet.h>

#include <postgres.h>
#include <utils/palloc.h>
#include <utils/builtins.h>
#include <utils/inet.h>

static int v4bitncmp(unsigned int a1, unsigned int a2, int bits);

/*
* Access macros. Add IPV6 support.
*/

#define ip_addrsize(inetptr) \
(((inet_struct *)VARDATA(inetptr))->family == AF_INET ? 4 : -1)

#define ip_family(inetptr) \
(((inet_struct *)VARDATA(inetptr))->family)

#define ip_bits(inetptr) \
(((inet_struct *)VARDATA(inetptr))->bits)

#define ip_v4addr(inetptr) \
(((inet_struct *)VARDATA(inetptr))->addr.ipv4_addr)

/*
* IP address reader.
*/

inet *
cidr_in(char *src)
{
int bits;
inet *dst;

	dst = palloc(VARHDRSZ + sizeof(inet_struct));
	if (dst == NULL)
	{
		elog(ERROR, "unable to allocate memory in cidr_in()");
		return (NULL);
	}
	/* First, try for an IP V4 address: */
	ip_family(dst) = AF_INET;
	bits = inet_cidr_pton(ip_family(dst), src, &ip_v4addr(dst), ip_addrsize(dst));
	if ((bits < 0) || (bits > 32))
	{
		/* Go for an IPV6 address here, before faulting out: */
		elog(ERROR, "could not parse \"%s\"", src);
		pfree(dst);
		return (NULL);
	}
	VARSIZE(dst) = VARHDRSZ
		+ ((char *) &ip_v4addr(dst) - (char *) VARDATA(dst))
		+ ip_addrsize(dst);
	ip_bits(dst) = bits;
	return (dst);
}

/*
* IP address output function.
*/

char *
cidr_out(inet *src)
{
char *dst,
tmp[sizeof("255.255.255.255/32")];

if (ip_family(src) == AF_INET)
{
/* It's an IP V4 address: */
if (inet_cidr_ntop(AF_INET, &ip_v4addr(src), ip_addrsize(src), ip_bits(src),
tmp, sizeof(tmp)) < 0)
{
elog(ERROR, "unable to print address (%s)", strerror(errno));
return (NULL);
}
}
else
{
/* Go for an IPV6 address here, before faulting out: */
elog(ERROR, "unknown address family (%d)", ip_family(src));
return (NULL);
}
dst = palloc(strlen(tmp) + 1);
if (dst == NULL)
{
elog(ERROR, "unable to allocate memory in cidr_out()");
return (NULL);
}
strcpy(dst, tmp);
return (dst);
}

/*
* Boolean tests for magnitude. Add V4/V6 testing!
*/

bool
cidr_lt(inet *a1, inet *a2)
{
if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
{
int order = v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2));

return ((order < 0) || ((order == 0) && (ip_bits(a1) < ip_bits(a2))));
}
else
{
/* Go for an IPV6 address here, before faulting out: */
elog(ERROR, "cannot compare address families %d and %d",
ip_family(a1), ip_family(a2));
return (FALSE);
}
}

bool
cidr_le(inet *a1, inet *a2)
{
return (inet_lt(a1, a2) || inet_eq(a1, a2));
}

bool
cidr_eq(inet *a1, inet *a2)
{
if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
{
return ((ip_bits(a1) == ip_bits(a2))
&& (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0));
}
else
{
/* Go for an IPV6 address here, before faulting out: */
elog(ERROR, "cannot compare address families %d and %d",
ip_family(a1), ip_family(a2));
return (FALSE);
}
}

bool
cidr_ge(inet *a1, inet *a2)
{
return (inet_gt(a1, a2) || inet_eq(a1, a2));
}

bool
cidr_gt(inet *a1, inet *a2)
{
if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
{
int order = v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2));

return ((order > 0) || ((order == 0) && (ip_bits(a1) > ip_bits(a2))));
}
else
{
/* Go for an IPV6 address here, before faulting out: */
elog(ERROR, "cannot compare address families %d and %d",
ip_family(a1), ip_family(a2));
return (FALSE);
}
}

bool
cidr_ne(inet *a1, inet *a2)
{
return (!inet_eq(a1, a2));
}

bool
cidr_sub(inet *a1, inet *a2)
{
if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
{
return ((ip_bits(a1) > ip_bits(a2))
&& (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2)) == 0));
}
else
{
/* Go for an IPV6 address here, before faulting out: */
elog(ERROR, "cannot compare address families %d and %d",
ip_family(a1), ip_family(a2));
return (FALSE);
}
}

bool
cidr_subeq(inet *a1, inet *a2)
{
if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
{
return ((ip_bits(a1) >= ip_bits(a2))
&& (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2)) == 0));
}
else
{
/* Go for an IPV6 address here, before faulting out: */
elog(ERROR, "cannot compare address families %d and %d",
ip_family(a1), ip_family(a2));
return (FALSE);
}
}

bool
cidr_sup(inet *a1, inet *a2)
{
if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
{
return ((ip_bits(a1) < ip_bits(a2))
&& (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0));
}
else
{
/* Go for an IPV6 address here, before faulting out: */
elog(ERROR, "cannot compare address families %d and %d",
ip_family(a1), ip_family(a2));
return (FALSE);
}
}

bool
cidr_supeq(inet *a1, inet *a2)
{
if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
{
return ((ip_bits(a1) <= ip_bits(a2))
&& (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0));
}
else
{
/* Go for an IPV6 address here, before faulting out: */
elog(ERROR, "cannot compare address families %d and %d",
ip_family(a1), ip_family(a2));
return (FALSE);
}
}

/*
* Comparison function for sorting. Add V4/V6 testing!
*/

int4
cidr_cmp(inet *a1, inet *a2)
{
if (ntohl(ip_v4addr(a1)) < ntohl(ip_v4addr(a2)))
return (-1);
else if (ntohl(ip_v4addr(a1)) > ntohl(ip_v4addr(a2)))
return (1);
return 0;
}

/*
* Bitwise comparison for V4 addresses. Add V6 implementation!
*/

static int
v4bitncmp(unsigned int a1, unsigned int a2, int bits)
{
unsigned long mask = 0;
int i;

for (i = 0; i < bits; i++)
mask = (mask >> 1) | 0x80000000;
a1 = ntohl(a1);
a2 = ntohl(a2);
if ((a1 & mask) < (a2 & mask))
return (-1);
else if ((a1 & mask) > (a2 & mask))
return (1);
return (0);
}

-- 
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 424 2871     (DoD#0082)    (eNTP)   |  what's for dinner.
#38Bruce Momjian
maillist@candle.pha.pa.us
In reply to: Noname (#37)
Re: [HACKERS] Re: inet/cidr/bind

Thus spake Bruce Momjian

If you define a fuction that can take inet or cidr type, I recommend you
define a typedef called something like "inet_or_cidr" that is the same
as inet, and use that in functions that can take either type.

Perhaps. We can look at that 6.4++. For now there will be redundancy.
Afterwards we'll look at how to fold them.

I hope you realize that that 6.4++ would have to be 6.5. We typically
don't to system table changes as part of minor releases, unless there is
a really good reason. It is hard to do for us and for the users.

-- 
  Bruce Momjian                        |  http://www.op.net/~candle
  maillist@candle.pha.pa.us            |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#39Paul A Vixie
paul@vix.com
In reply to: Noname (#30)
Re: [HACKERS] Re: inet/cidr/bind

no. the last three inputs are not valid where a host address is expected.

Can you amplify? Is it correct as far as cidr goes? If so, I have no
problem making it an error for the inet type. My thinking was based
on the earlier concept of having one type and accepting networks in it.
If we have the separate cidr type then I guess inet should always require
4 octets (until ipv6 anyway) and cidr should be used for networks.

Networks do not have to have all four octets specified, only enough octets
to cover the prefix length that's given. Networks should have default
netmasks based on classful assumptions. Networks never have any bits beyond
their prefix length, which is why the question of "nonzero host part" does
not even really arise. There is no "host part" in a network. And in my
concept of them, they are variably sized.

How about something like 192.63.0.0/16? Should that be an error under the
inet type since it is the network? I am thinking not since technically
192.63.0.0 is a valid host under 192.63/16 although it is generally
avoided since there is still software that assumes that it is the
network or even the broadcast.

The all-zeros host address is available and value, but as you say, deprecated.

so shall i test the inet_cidr_ functions and punt them on in?

Ok, before I have a reality shift, the inet_cidr_ functions are simply
the original inet_net_ functions renamed, right?

No. The inet_net_ functions describe CIDRized networks. The inet_cidr_
functions, which I've written but not yet committed to BIND 8.next, are
new. I am absolutely loathe to submit them at this point, since the act
of bridging host addresses and their prefix lengths makes no sense to me.

Here's a cisco showing a CIDR block (mine, as it turns out):

palo-alto>sho ip rou 204.152.184.0
Routing entry for 204.152.184.0/21, supernet
Known via "bgp 1280", distance 20, metric 0
Tag 3557, type external
Last update from 198.32.176.3 2w0d ago
Routing Descriptor Blocks:
* 198.32.176.3, from 198.32.176.3, 2w0d ago
Route metric is 0, traffic share count is 1
AS Hops 1

Here's a BSD/OS box showing a bunch of CIDR blocks (inside my network):

# netstat -rn
Destination Gateway Flags Refs Use Interface
default 204.152.184.4 UG 0 103154609 de1
127 127.0.0.1 UR 0 0 lo0
127.0.0.1 127.0.0.1 UH 0 59294 lo0
192.5.5.1 204.152.184.19 UGH 0 1160628 de0
192.5.5.2 204.152.184.19 UGH 0 507879 de0
192.5.5.88/29 204.152.184.19 UG 0 4 de0
192.5.5.96/27 204.152.184.19 UG 0 35150 de0
192.5.5.124/30 204.152.184.19 UG 0 12361 de0
192.5.5.241 204.152.184.4 UGH 0 55164 de1
198.32.176 204.152.184.1 UG 0 15250 de1
198.32.176.6 204.152.184.1 UGHc 0 76 de1
204.152.184/28 link#2 UC 0 0 de1
204.152.184.1 0:c0:95:e0:1e:1c UHLc 4 493 de1
204.152.184.3 0:c0:95:e0:2e:8c UHLc 0 1 lo0
204.152.184.4 0:c0:95:e0:1e:24 UHLc 4 7125 de1
204.152.184.5 0:c0:95:e0:26:80 UHLc 1 0 de1
204.152.184.16/29 link#1 UC 0 0 de0
^C

The things which are "hosts" have four octets, are of fixed length, and do not
have netmasks. The things which are "networks" have some other number of
octets, are variably sized, and do have netmasks (actually, prefix lengths).

At the risk of reopening a discussion which ought to have been closed a long
while back, I suggest that polymorphism is bad and that an INET type which is
built out of BIND's inet_net_ functions is perfectly capable of holding a
host address (since /32 is the default if all four octets are specified),
and that we run absolutely zero risk if we call the type INET, add indexing
linkages for it, and get outta town.

There is an argument for a sugartype called IHOST which generates a /32 INET
but uses inet_pton() and inet_ntop() for parsing/printing so as to avoid the
"/%d" that nobody needs to see and also to ensure that only fully formed host
addresses can be input.

There is an argument for another, completely separate type, called MACADDR,
which is an IEEE 48-bit address (suitable for ethernet or fddi arp tables).

There is no argument I know of for a type which combines the host address and
the netmask of its interface. I've got applications in mind for each of the
above three types -- has anybody got a specific application they want to build
which requires a CIDR-like host address which is of fixed size, has the
ability to preserve the "unset"-ness of the prefix length from input through
storage to output, and also has the ability to preserve a particular prefix
length from input through storage to output?

I'll use INET in a registry database like IANA's or InterNIC's.

I'll use INET, IHOST and MACADDR in a distributed DHCP database.

What would anybody use a mixture of INET and IHOST for, that they could not
do just as easily with a pair of IHOST's?

Forget the number theory for a moment and let's talk about applications which
are uniquely enabled by any new type we consider. Once that's done, we can
talk about avoiding unfortunate overlaps.

I've got the code done for supporting hosts-with-prefixes, but I don't like it
and I would not use it in any PgSQL application I can imagine. Help?

#40Paul A Vixie
paul@vix.com
In reply to: Bruce Momjian (#36)
Re: [HACKERS] Re: inet/cidr/bind

There is already concern that we are too close to the 6.4 final date to
do anything with the INET type. I am hearing that from another
developer.

Yes.

I am not sure what to advise, but adding a new type is not trivial. It
is going to require an initdb by everyone, because it is going to be in
the regression test.

I propose that we rename CIDR to INET, base it on the existing inet_net_*
functions, and have done with it. We can add IHOST next time.

My personal opinion is that I am not ready to add a new type, and new
duplicate functions for that type, this close to final. I can add the
type, and the pg_proc/indexing pointers to link in the existing
inet functions, but full type inclusion is too much, I think.

I don't know how to help with this.

For example, I have an inet_ops entry in pg_class. I don't want to add
an cidr_ops function that behaves exactly the same. If we can't do this
right, then we will not do it for 6.4. My experience is that dumping
partial solutions into 250k lines of code is a bad thing.

Yes.

So, if people really want it, it has to be _good_. If is not that
important, it can wait.

I believe that I am to blame for the last minute nature of this, because I
was not properly focused on applications during the much earlier discussion.

Because we're at the end of our time, I propose that we rename the type to
INET, use the existing inet_net_ functions, and blow the bolts.

#41Noname
darcy@druid.net
In reply to: Paul A Vixie (#39)
Re: [HACKERS] Re: inet/cidr/bind

Thus spake Paul A Vixie

Networks do not have to have all four octets specified, only enough octets
to cover the prefix length that's given. Networks should have default
netmasks based on classful assumptions. Networks never have any bits beyond
their prefix length, which is why the question of "nonzero host part" does
not even really arise. There is no "host part" in a network. And in my
concept of them, they are variably sized.

I think we (at least I) are still confused about what the types are. I
see two types on the table;

a) A type to hold networks only
b) A type to hold hosts with optional netmasks

Can we agree that these are the two types we are discussing? If so can we
agree on which is which? I have been assuming that A was cidr and B was
inet but perhaps I have it backwards.

The all-zeros host address is available and value, but as you say, deprecated.

But not illegal, right?

No. The inet_net_ functions describe CIDRized networks. The inet_cidr_
functions, which I've written but not yet committed to BIND 8.next, are
new. I am absolutely loathe to submit them at this point, since the act
of bridging host addresses and their prefix lengths makes no sense to me.

OK, so it looks like I had it backwards all along. So we can just put the
inet.c function back in exactly as it was then? If we agree on this then
we are half way there and at least we have something for 6.4 right now.

At the risk of reopening a discussion which ought to have been closed a long
while back, I suggest that polymorphism is bad and that an INET type which is
built out of BIND's inet_net_ functions is perfectly capable of holding a
host address (since /32 is the default if all four octets are specified),
and that we run absolutely zero risk if we call the type INET, add indexing
linkages for it, and get outta town.

There is an argument for a sugartype called IHOST which generates a /32 INET
but uses inet_pton() and inet_ntop() for parsing/printing so as to avoid the
"/%d" that nobody needs to see and also to ensure that only fully formed host
addresses can be input.

So host only - no additional information carried in the type?

There is an argument for another, completely separate type, called MACADDR,
which is an IEEE 48-bit address (suitable for ethernet or fddi arp tables).

Nothing to do with our current discussion, right? You are just mentioning
it for completeness and we shall never speak of it again, or at least not
till after 6.4?

There is no argument I know of for a type which combines the host address and
the netmask of its interface. I've got applications in mind for each of the
above three types -- has anybody got a specific application they want to build
which requires a CIDR-like host address which is of fixed size, has the
ability to preserve the "unset"-ness of the prefix length from input through
storage to output, and also has the ability to preserve a particular prefix
length from input through storage to output?

Radius server for Ascend terminal servers.

-- 
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 424 2871     (DoD#0082)    (eNTP)   |  what's for dinner.
#42Noname
darcy@druid.net
In reply to: Bruce Momjian (#36)
Re: [HACKERS] Re: inet/cidr/bind

Thus spake Bruce Momjian

However, let's get the two types in right now with two separate groups
of functions and fold them after the release. It won't change the
user interface. Unless we think we can do it quickly.

In any case, maybe we can add the flag now since we figure we'll need
it later anyway.

Once we put entries in the system tables, those really are not going to
change dramatically until 6.5.

While I would like everything in there now, I can live with this as long
as the user interface doesn't change.

How about this? We now have an inet type pretty much completed. Let's
put that back in right now. copy all the files involved, substitute
inet to cidr in the function names and make it the new cidr type. Once
we agree on which one is the host+netmask type add the extra functions
for netmask, masklen, host, network_without_bits, network_with_bits and
broadcast making them stubs if necessary. I'll get my code into the
right file as soon as possible. Later we can fold things in better
but we can do it without changing the catalogues. If it makes it more
efficient we can change the catalogue where 6.5 comes out.

If we can do this right away I think we have a good chance of getting
it into 6.4 properly anyway.

My personal opinion is that I am not ready to add a new type, and new
duplicate functions for that type, this close to final. I can add the
type, and the pg_proc/indexing pointers to link in the existing
inet functions, but full type inclusion is too much, I think.

For example, I have an inet_ops entry in pg_class. I don't want to add
an cidr_ops function that behaves exactly the same. If we can't do this
right, then we will not do it for 6.4. My experience is that dumping
partial solutions into 250k lines of code is a bad thing.

Of course this is your decision. We have the inet type now and as long
as we know what that type is, we can always add the other for 6.5 if
we can't get it in now.

So, if people really want it, it has to be _good_. If is not that
important, it can wait.

So far less than a half dozen people are really involved in this discussion.
How about a quick straw poll of who really wants this in?

These are my opinions, and of course, can be over-ruled.

Not if you need to do the work on the catalogues they can't. :-)

-- 
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 424 2871     (DoD#0082)    (eNTP)   |  what's for dinner.
#43Noname
darcy@druid.net
In reply to: Bruce Momjian (#36)
Re: [HACKERS] Re: inet/cidr/bind

Thus spake Bruce Momjian

If people really want the INET/CIDR type for 6.4, we are going to need
tremendous effort to pull this off. That means good, clean code,
documenation, and testing, regression tests, and soon.

Would it be helpful to discuss this in a more direct matter? I am sitting
in #postgreSQL on EFNet (IRC) if anyone wants to join me there.

-- 
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 424 2871     (DoD#0082)    (eNTP)   |  what's for dinner.
#44Paul A Vixie
paul@vix.com
In reply to: Noname (#41)
Re: [HACKERS] Re: inet/cidr/bind

I think we (at least I) are still confused about what the types are. I
see two types on the table;

a) A type to hold networks only
b) A type to hold hosts with optional netmasks

Can we agree that these are the two types we are discussing? If so can we
agree on which is which? I have been assuming that A was cidr and B was
inet but perhaps I have it backwards.

I am challenging the (b) type above. I see three types:

INET holds CIDRized networks
IHOST holds host end-addresses
MACADDR holes IEEE 48-bit ether/fddi addresses

As to whether the type names are backwards, probably not. It's only if we
postulate type (b) above that an ambiguity arises as to whether the type we
were calling CIDR refers to hosts+netmasks or to CIDRized networks.

Certainly the new inet_cidr_ functions were written for the former while the
existing inet_net_ functions were written for the latter.

The all-zeros host address is available ..., but as you say, deprecated.

But not illegal, right?

Nope, just unusable on Suns.

No. The inet_net_ functions describe CIDRized networks. The inet_cidr_
functions, which I've written but not yet committed to BIND 8.next, are
new. I am absolutely loathe to submit them at this point, since the act
of bridging host addresses and their prefix lengths makes no sense to me.

OK, so it looks like I had it backwards all along. So we can just put the
inet.c function back in exactly as it was then? If we agree on this then
we are half way there and at least we have something for 6.4 right now.

Agreed.

There is an argument for a sugartype called IHOST which generates a /32
INET but uses inet_pton() and inet_ntop() for parsing/printing so as to
avoid the "/%d" that nobody needs to see and also to ensure that only
fully formed host addresses can be input.

So host only - no additional information carried in the type?

That would be my preference. But as it would be the same underlying type,
it would be possible to ask for all supernet INETs of some IHOST -- the
supernet/subnet comparison functions would be inherently polymorphic. I've
already got an application in mind that would benefit from this polymorphism.

There is an argument for another, completely separate type, called MACADDR,
which is an IEEE 48-bit address (suitable for ethernet or fddi arp tables).

Nothing to do with our current discussion, right? You are just mentioning
it for completeness and we shall never speak of it again, or at least not
till after 6.4?

I'd thought that the fellow who wrote ip_and_mac had already submitted the
MACADDR type. If not, then clearly it is way too late to consider it for 6.4.

... -- has anybody got a specific application they want to build which
requires a CIDR-like host address which is of fixed size, has the ability
to preserve the "unset"-ness of the prefix length from input through
storage to output, and also has the ability to preserve a particular prefix
length from input through storage to output?

Radius server for Ascend terminal servers.

Is there no way to accomplish this without efficiency loss using a pair of
IHOSTs, one for the host address and one for the netmask?

I note that polymorphism of the supernet/subnet tests between (a) and (b) as
denoted in the top of the text I've quoted in this message is a lot more work
than the inherent polymorphism of supernet/subnet tests between an INET and
an IHOST as I've proposed them here.

#45Matthew N. Dodd
winter@jurai.net
In reply to: Paul A Vixie (#39)
Re: [HACKERS] Re: inet/cidr/bind

I'm voting that the rest of the peanut gallary sit down and allow
PostgreSQL to adopt Vixie's world vision of the INET type. If after the
release it is found to be lacking it can be addressed then.

Lets give the man some credit; he's got a better idea of what will be
useful than anyone else I've seen here. Everyone else seems to be
stumbling around attempting to argue a point while trying to figure out
what the heck they're arguing about. If you don't understand what Paul is
trying to do, then sit down, read a few books and come back when you do.

This whole issue is really heading towards a stalemate otherwise.

As usual, feel free to ignore me.

Paul, thanks for taking the time to educate everyone here. Your patience
is appriciated and I only hope that the features you need will pan out in
the release.

On Mon, 19 Oct 1998, Paul A Vixie wrote:

no. the last three inputs are not valid where a host address is expected.

Can you amplify? Is it correct as far as cidr goes? If so, I have no
problem making it an error for the inet type. My thinking was based
on the earlier concept of having one type and accepting networks in it.
If we have the separate cidr type then I guess inet should always require
4 octets (until ipv6 anyway) and cidr should be used for networks.

Networks do not have to have all four octets specified, only enough octets
to cover the prefix length that's given. Networks should have default
netmasks based on classful assumptions. Networks never have any bits beyond
their prefix length, which is why the question of "nonzero host part" does
not even really arise. There is no "host part" in a network. And in my
concept of them, they are variably sized.

How about something like 192.63.0.0/16? Should that be an error under the
inet type since it is the network? I am thinking not since technically
192.63.0.0 is a valid host under 192.63/16 although it is generally
avoided since there is still software that assumes that it is the
network or even the broadcast.

The all-zeros host address is available and value, but as you say, deprecated.

so shall i test the inet_cidr_ functions and punt them on in?

Ok, before I have a reality shift, the inet_cidr_ functions are simply
the original inet_net_ functions renamed, right?

No. The inet_net_ functions describe CIDRized networks. The inet_cidr_
functions, which I've written but not yet committed to BIND 8.next, are
new. I am absolutely loathe to submit them at this point, since the act
of bridging host addresses and their prefix lengths makes no sense to me.

Here's a cisco showing a CIDR block (mine, as it turns out):

palo-alto>sho ip rou 204.152.184.0
Routing entry for 204.152.184.0/21, supernet
Known via "bgp 1280", distance 20, metric 0
Tag 3557, type external
Last update from 198.32.176.3 2w0d ago
Routing Descriptor Blocks:
* 198.32.176.3, from 198.32.176.3, 2w0d ago
Route metric is 0, traffic share count is 1
AS Hops 1

Here's a BSD/OS box showing a bunch of CIDR blocks (inside my network):

# netstat -rn
Destination Gateway Flags Refs Use Interface
default 204.152.184.4 UG 0 103154609 de1
127 127.0.0.1 UR 0 0 lo0
127.0.0.1 127.0.0.1 UH 0 59294 lo0
192.5.5.1 204.152.184.19 UGH 0 1160628 de0
192.5.5.2 204.152.184.19 UGH 0 507879 de0
192.5.5.88/29 204.152.184.19 UG 0 4 de0
192.5.5.96/27 204.152.184.19 UG 0 35150 de0
192.5.5.124/30 204.152.184.19 UG 0 12361 de0
192.5.5.241 204.152.184.4 UGH 0 55164 de1
198.32.176 204.152.184.1 UG 0 15250 de1
198.32.176.6 204.152.184.1 UGHc 0 76 de1
204.152.184/28 link#2 UC 0 0 de1
204.152.184.1 0:c0:95:e0:1e:1c UHLc 4 493 de1
204.152.184.3 0:c0:95:e0:2e:8c UHLc 0 1 lo0
204.152.184.4 0:c0:95:e0:1e:24 UHLc 4 7125 de1
204.152.184.5 0:c0:95:e0:26:80 UHLc 1 0 de1
204.152.184.16/29 link#1 UC 0 0 de0
^C

The things which are "hosts" have four octets, are of fixed length, and do not
have netmasks. The things which are "networks" have some other number of
octets, are variably sized, and do have netmasks (actually, prefix lengths).

At the risk of reopening a discussion which ought to have been closed a long
while back, I suggest that polymorphism is bad and that an INET type which is
built out of BIND's inet_net_ functions is perfectly capable of holding a
host address (since /32 is the default if all four octets are specified),
and that we run absolutely zero risk if we call the type INET, add indexing
linkages for it, and get outta town.

There is an argument for a sugartype called IHOST which generates a /32 INET
but uses inet_pton() and inet_ntop() for parsing/printing so as to avoid the
"/%d" that nobody needs to see and also to ensure that only fully formed host
addresses can be input.

There is an argument for another, completely separate type, called MACADDR,
which is an IEEE 48-bit address (suitable for ethernet or fddi arp tables).

There is no argument I know of for a type which combines the host address and
the netmask of its interface. I've got applications in mind for each of the
above three types -- has anybody got a specific application they want to build
which requires a CIDR-like host address which is of fixed size, has the
ability to preserve the "unset"-ness of the prefix length from input through
storage to output, and also has the ability to preserve a particular prefix
length from input through storage to output?

I'll use INET in a registry database like IANA's or InterNIC's.

I'll use INET, IHOST and MACADDR in a distributed DHCP database.

What would anybody use a mixture of INET and IHOST for, that they could not
do just as easily with a pair of IHOST's?

Forget the number theory for a moment and let's talk about applications which
are uniquely enabled by any new type we consider. Once that's done, we can
talk about avoiding unfortunate overlaps.

I've got the code done for supporting hosts-with-prefixes, but I don't like it
and I would not use it in any PgSQL application I can imagine. Help?

--
| Matthew N. Dodd | 78 280Z | 75 164E | 84 245DL | FreeBSD/NetBSD/Sprite/VMS |
| winter@jurai.net | This Space For Rent | ix86,sparc,m68k,pmax,vax |
| http://www.jurai.net/~winter | Are you k-rad elite enough for my webpage? |

#46Bruce Momjian
maillist@candle.pha.pa.us
In reply to: Paul A Vixie (#40)
Re: [HACKERS] Re: inet/cidr/bind

There is already concern that we are too close to the 6.4 final date to
do anything with the INET type. I am hearing that from another
developer.

Yes.

I am not sure what to advise, but adding a new type is not trivial. It
is going to require an initdb by everyone, because it is going to be in
the regression test.

I propose that we rename CIDR to INET, base it on the existing inet_net_*
functions, and have done with it. We can add IHOST next time.

No need. It is already called INET.

My personal opinion is that I am not ready to add a new type, and new
duplicate functions for that type, this close to final. I can add the
type, and the pg_proc/indexing pointers to link in the existing
inet functions, but full type inclusion is too much, I think.

I don't know how to help with this.

I will do the work, but am hesitant to do too much system table fiddling
at this point.

For example, I have an inet_ops entry in pg_class. I don't want to add
an cidr_ops function that behaves exactly the same. If we can't do this
right, then we will not do it for 6.4. My experience is that dumping
partial solutions into 250k lines of code is a bad thing.

Yes.

So, if people really want it, it has to be _good_. If is not that
important, it can wait.

I believe that I am to blame for the last minute nature of this, because I
was not properly focused on applications during the much earlier discussion.

Because we're at the end of our time, I propose that we rename the type to
INET, use the existing inet_net_ functions, and blow the bolts.

Fortunately, it is already called INET. We have all the system catalogs
wired for the type. We just need working versions of some of those
functions, and D'Arcy can go at it.

If we are good, this may not even require an initdb, because the changes
were made long ago for the INET type.

-- 
  Bruce Momjian                        |  http://www.op.net/~candle
  maillist@candle.pha.pa.us            |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#47Bruce Momjian
maillist@candle.pha.pa.us
In reply to: Paul A Vixie (#44)
Re: [HACKERS] Re: inet/cidr/bind

There is an argument for another, completely separate type, called MACADDR,
which is an IEEE 48-bit address (suitable for ethernet or fddi arp tables).

Nothing to do with our current discussion, right? You are just mentioning
it for completeness and we shall never speak of it again, or at least not
till after 6.4?

I'd thought that the fellow who wrote ip_and_mac had already submitted the
MACADDR type. If not, then clearly it is way too late to consider it for 6.4.

From psql's \dT command:

macaddr |MAC address
inet |IP address

... -- has anybody got a specific application they want to build which
requires a CIDR-like host address which is of fixed size, has the ability
to preserve the "unset"-ness of the prefix length from input through
storage to output, and also has the ability to preserve a particular prefix
length from input through storage to output?

Radius server for Ascend terminal servers.

Is there no way to accomplish this without efficiency loss using a pair of
IHOSTs, one for the host address and one for the netmask?

I note that polymorphism of the supernet/subnet tests between (a) and (b) as
denoted in the top of the text I've quoted in this message is a lot more work
than the inherent polymorphism of supernet/subnet tests between an INET and
an IHOST as I've proposed them here.

I can't comment on the rest of this, because I don't understand it.

-- 
  Bruce Momjian                        |  http://www.op.net/~candle
  maillist@candle.pha.pa.us            |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#48Noname
darcy@druid.net
In reply to: Paul A Vixie (#44)
Re: [HACKERS] Re: inet/cidr/bind

Thus spake Paul A Vixie

I think we (at least I) are still confused about what the types are. I
see two types on the table;

a) A type to hold networks only
b) A type to hold hosts with optional netmasks

Can we agree that these are the two types we are discussing? If so can we
agree on which is which? I have been assuming that A was cidr and B was
inet but perhaps I have it backwards.

I am challenging the (b) type above. I see three types:

INET holds CIDRized networks

So that's the type a above.

IHOST holds host end-addresses
MACADDR holes IEEE 48-bit ether/fddi addresses

As to whether the type names are backwards, probably not. It's only if we
postulate type (b) above that an ambiguity arises as to whether the type we
were calling CIDR refers to hosts+netmasks or to CIDRized networks.

Originally I thought we were calling 'a' the cidr type and 'b' the inet
type hence my confusion. I still think that that is the better but since
we have working code and it is already named, I guess we should go with it.

For convenience, let's call my 'b' type above a CHOST type for CIDRized
host. So hopefully we all have the types straight.

INET holds CIDRized networks
IHOST holds host end-addresses
CHOST host plus netmask.

Certainly the new inet_cidr_ functions were written for the former while the
existing inet_net_ functions were written for the latter.

So it is designed for CHOST then? Well, you know my opinion.

The all-zeros host address is available ..., but as you say, deprecated.

But not illegal, right?

Nope, just unusable on Suns.

<TANGENT>Right. I wonder if we should consider making this a compile-time
option or something post-6.4.</TANGENT>

No. The inet_net_ functions describe CIDRized networks. The inet_cidr_
functions, which I've written but not yet committed to BIND 8.next, are
new. I am absolutely loathe to submit them at this point, since the act
of bridging host addresses and their prefix lengths makes no sense to me.

OK, so it looks like I had it backwards all along. So we can just put the
inet.c function back in exactly as it was then? If we agree on this then
we are half way there and at least we have something for 6.4 right now.

Agreed.

So unless someone is violently opposed then Bruce, can you put it back to
the way it was before I submitted my patch to inet.c? That gives us the
INET type as defined above.

So host only - no additional information carried in the type?

That would be my preference. But as it would be the same underlying type,
it would be possible to ask for all supernet INETs of some IHOST -- the
supernet/subnet comparison functions would be inherently polymorphic. I've
already got an application in mind that would benefit from this polymorphism.

You think it should be a differnt type then? You can do it with one if
you use /32 for hosts, right? In fact, make a naked ip imply /32 for
INET type but /-1 for CHOST type (if we go with it.)

In fact, forget the -1 idea. Default both types to /32 and never print
the bits for the CHOST type. That simplifies the calculations.

I'd thought that the fellow who wrote ip_and_mac had already submitted the
MACADDR type. If not, then clearly it is way too late to consider it for 6.4.

Actually, I don't even know if that is in or not. In any case, it either
is or isn't. We don't need to dwell on it. (So why am I? :-) )

... -- has anybody got a specific application they want to build which
requires a CIDR-like host address which is of fixed size, has the ability
to preserve the "unset"-ness of the prefix length from input through
storage to output, and also has the ability to preserve a particular prefix
length from input through storage to output?

Radius server for Ascend terminal servers.

Is there no way to accomplish this without efficiency loss using a pair of
IHOSTs, one for the host address and one for the netmask?

It becomes messy. In fact, I would use an integer for the netmask in that
situation.

I note that polymorphism of the supernet/subnet tests between (a) and (b) as
denoted in the top of the text I've quoted in this message is a lot more work
than the inherent polymorphism of supernet/subnet tests between an INET and
an IHOST as I've proposed them here.

That's why I'm saying get rid of the -1 hack that I originally proposed.

So, INET is in. The question is what to do with IHOST and CHOST. I
think CHOST should go in. You can use it for IHOST too.

I'm going to talk to Bruce in IRC now. I have another idea for making
one type for all 3 but I'm not sure of some details of the type system.

-- 
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 424 2871     (DoD#0082)    (eNTP)   |  what's for dinner.
#49Noname
darcy@druid.net
In reply to: Matthew N. Dodd (#45)
Re: [HACKERS] Re: inet/cidr/bind

Thus spake Matthew N. Dodd

I'm voting that the rest of the peanut gallary sit down and allow
PostgreSQL to adopt Vixie's world vision of the INET type. If after the
release it is found to be lacking it can be addressed then.

Actually, we already have. The discussion is only over adding a second
type and what, exactly, it should be.

-- 
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 424 2871     (DoD#0082)    (eNTP)   |  what's for dinner.
#50Paul A Vixie
paul@vix.com
In reply to: Matthew N. Dodd (#45)
Re: [HACKERS] Re: inet/cidr/bind

Paul, thanks for taking the time to educate everyone here. Your patience
is appriciated and I only hope that the features you need will pan out in
the release.

Be careful here. My purported credentials in the networking field do not
necessarily translate to expertise in the database field. I am a student
of computer languages, especially their type systems. INET can be seen as
a supertype of (which means it can contain all the values) of IHOST. But
there is no subtype or supertype relationship between CHOST and either INET
or IHOST. Since Postgres is a very typey database, I am attracted to the
simple approach of creating INET (which is done now?), later on creating
IHOST as a subtype of it with different parsing/printing functions, and
using a pair of IHOSTs for any application which needs what CHOST does.

That's the computer language typing system approach, and the networking
approach. I'm confident in those fields. I am less so in the database
field -- the last database application I was paid to write was in 1981,
and that database was not even relational let alone object oriented.

IHOST and INET is how I'd implement this functionality in, say, Modula-3.
It also makes for a relatively compact and unambiguous (that is, easy to
generate a complete set of unit tests for) implementation. But it's very
possible that I'm just an uneducated dolt when it comes to relational
object oriented databases and that anyone with more experience than I have
would automatically gravitate toward something like CHOST.

Quoting Mike Smith, "I am only an egg."

#51Paul A Vixie
paul@vix.com
In reply to: Noname (#48)
Re: [HACKERS] Re: inet/cidr/bind

Originally I thought we were calling 'a' the cidr type and 'b' the inet
type hence my confusion. I still think that that is the better but since
we have working code and it is already named, I guess we should go with it.

This sounds like consensus to me. Bruce said the same.

So host only - no additional information carried in the type?

That would be my preference. But as it would be the same underlying type,
it would be possible to ask for all supernet INETs of some IHOST -- the
supernet/subnet comparison functions would be inherently polymorphic. I've
already got an application in mind that would benefit from this
polymorphism.

You think it should be a differnt type then? You can do it with one if
you use /32 for hosts, right? In fact, make a naked ip imply /32 for
INET type but /-1 for CHOST type (if we go with it.)

In IHOST as I proposed it, it would have the same on-disk format as INET,
but with a fixed /32 and with different parsing and printing functions:
the parser would object unless all four octets and no /## was specified,
and the printer would just print the octets and elide the /32. There are
functions in BIND, i.e., inet_pton() and inet_ntop(), which do that kind
of parsing and printing.

In fact, forget the -1 idea. Default both types to /32 and never print
the bits for the CHOST type. That simplifies the calculations.

If we're never printing the bits for CHOST, it's not different from IHOST?

Is there no way to accomplish this without efficiency loss using a pair of
IHOSTs, one for the host address and one for the netmask?

It becomes messy. In fact, I would use an integer for the netmask in that
situation.

"Messy" is not as strong a concern as performance, though, is it? If the
only time we need a host address and a netmask together is when a Radius
server using an SQL backend had to do some string arithmetic before sending
the Radius reply, then that's not as compelling an argument as it might be.

#52Noname
darcy@druid.net
In reply to: Paul A Vixie (#51)
Re: [HACKERS] Re: inet/cidr/bind

Thus spake Paul A Vixie

You think it should be a differnt type then? You can do it with one if
you use /32 for hosts, right? In fact, make a naked ip imply /32 for
INET type but /-1 for CHOST type (if we go with it.)

In IHOST as I proposed it, it would have the same on-disk format as INET,
but with a fixed /32 and with different parsing and printing functions:
the parser would object unless all four octets and no /## was specified,
and the printer would just print the octets and elide the /32. There are
functions in BIND, i.e., inet_pton() and inet_ntop(), which do that kind
of parsing and printing.

In fact, forget the -1 idea. Default both types to /32 and never print
the bits for the CHOST type. That simplifies the calculations.

If we're never printing the bits for CHOST, it's not different from IHOST?

I meant default to /32 if it isn't specified. If it is then use what is
specified and print it if it isn't 32. So:

Input Stored as Output as
========= ========= =========
198.96.119.226/28 198.96.119.226/28 198.96.119.226/28
198.96.119.226/32 198.96.119.226/32 198.96.119.226
198.96.119.226 198.96.119.226/32 198.96.119.226

The middle one is the hairy one. Using -1 for unspecified let's us
output /32 if that was what was input. If we can live with not
printing /32 ever then we can simplify the handling.

Is there no way to accomplish this without efficiency loss using a pair of
IHOSTs, one for the host address and one for the netmask?

It becomes messy. In fact, I would use an integer for the netmask in that
situation.

"Messy" is not as strong a concern as performance, though, is it? If the
only time we need a host address and a netmask together is when a Radius
server using an SQL backend had to do some string arithmetic before sending
the Radius reply, then that's not as compelling an argument as it might be.

Actually, what is stored in the database (using CHOST) is exactly what
the terminal server needs - no calculations. To be complete I would
need to use the following to store everything I need without CHOST.

network::inet
gateway::ihost
masklen::integer

Now I guess I could get the masklen from the network but even then it
isn't straightforward since I would have to do string operations on
it to extract the bits after the slash. Either way it now becomes
possible for the two to get out of sync so now I have to also check
the network and gateway to make sure that the latter is within the
former every time I use it.

With CHOST I just select the field and pass it to the Radius function
that called me.

-- 
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 424 2871     (DoD#0082)    (eNTP)   |  what's for dinner.
#53Noname
darcy@druid.net
In reply to: Noname (#52)
Re: [HACKERS] Re: inet/cidr/bind

Ok, I have posted the patches for the inet type functions and Bruce has
applied it. The functions added are inet_netmask(), inet_broadcast() and
inet_masklen(). The other ones I mentioned before don't apply to
this type.

Next issue is the names given to the functions in the user API. At
the moment they just have the same names as the underlying functions
but I think they should be netmask(), broadcast() and masklen().
Does anyone disagree?

-- 
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 424 2871     (DoD#0082)    (eNTP)   |  what's for dinner.