Thread: 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.
> 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.
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.
> 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, Pennsylvania19026
> > 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.42192.4.13.42 255.255.255.0192.4.13.42/32192.4.13.42/32 255.255.255.0 and these are networks: 192.63.91.234/28192.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, Pennsylvania19026
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.
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.
> 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?
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 > -----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? > >
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.
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.
> 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, Pennsylvania19026
> 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, Pennsylvania19026
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.
> 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, Pennsylvania19026
> 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, Pennsylvania19026
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 IPV6address 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, beforefaulting 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, beforefaulting 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.
> 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, Pennsylvania19026
> > 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.0Routing entry for 204.152.184.0/21, supernet Known via "bgp 1280", distance 20, metric0 Tag 3557, type external Last update from 198.32.176.3 2w0d ago Routing Descriptor Blocks: * 198.32.176.3, from198.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 -rnDestination Gateway Flags Refs Use Interfacedefault 204.152.184.4 UG 0 103154609 de1127 127.0.0.1 UR 0 0 lo0127.0.0.1 127.0.0.1 UH 0 59294 lo0192.5.5.1 204.152.184.19 UGH 0 1160628 de0192.5.5.2 204.152.184.19 UGH 0 507879 de0192.5.5.88/29 204.152.184.19 UG 0 4 de0192.5.5.96/27 204.152.184.19 UG 0 35150 de0192.5.5.124/30 204.152.184.19 UG 0 12361 de0192.5.5.241 204.152.184.4 UGH 0 55164 de1198.32.176 204.152.184.1 UG 0 15250 de1198.32.176.6 204.152.184.1 UGHc 0 76 de1204.152.184/28 link#2 UC 0 0 de1204.152.184.1 0:c0:95:e0:1e:1c UHLc 4 493 de1204.152.184.3 0:c0:95:e0:2e:8c UHLc 0 1 lo0204.152.184.4 0:c0:95:e0:1e:24 UHLc 4 7125 de1204.152.184.5 0:c0:95:e0:26:80 UHLc 1 0 de1204.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?
> 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.
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.
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.
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.
> 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 networksIHOST holds host end-addressesMACADDR 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.
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? |
> > 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, Pennsylvania19026
> > > 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, Pennsylvania19026
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.
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.
> 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."
> 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.
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.