2022-01-25
Giving things an IP address is dangerous (to them)
We run a DHCP server for those of our internal 'sandbox' networks that are interested in assigning IPs that way (some people prefer static allocation). Most of those networks only give static IPs to already known machines, without an 'open' pool of IP addresses for unknown ones. One entirely predictable result of this (when combined with our variegated user population) is a certain number of unknown machines on various of these networks that are forever plaintively broadcasting to ask for an IP address, often pretty frequently. One annoying effect of this is a lot of clutter in our DHCP server logs.
Every so often when I look at the logs and see the clutter, I once again have the clever idea of just adding some dummy DHCP entries for the more prolific of these machines. It would be easy enough to hand out completely unroutable IP addresses to these machines, ones that aren't even on the network's subnet and that the firewall would block anyway. Since there aren't all that many of these machines, we could theoretically even give each of them their own little /28 or so with nothing else on it. This would at least get them to shut up and de-clutter our DHCP logs so that we have a better chance of seeing useful information and genuine issues.
Then I think a bit more and toss this clever idea out the window (again).
The problem with this clever idea is that giving random things an IP address is dangerous, and not just to other things on your network. Once something has an IP address, other things with an IP address can now find it and talk to it. It doesn't necessarily matter that those other machines are nominally on a different network; that can be worked around in various ways, possibly even accidentally (considering various forms of broadcast, multicast, and so on). By putting these machines on off-subnet IP addresses, we would also make them stand out like a sore thumb to anything looking for anomalies. One they had an IP address, it's very likely that these machines would send out various sorts of traffic that would make them visible, and even if they don't do anything else they will periodically renew their DHCP leases, exposing themselves via that traffic.
What makes this more dangerous is that it's likely that these are neglected devices, ones that no one even thinks have an IP (or are supposed to have one). People tend to notice when their actual servers need an IP and don't have one; they may not even know that their network switches, the IPMIs of their servers, and other miscellany are all asking to get on the network too. Many of these devices probably have default logins and passwords, alarming security holes, or both, and some of them create security vulnerabilities in other machines (most obviously IPMIs for servers). These are some of the last thing that we should be casually putting on the network with an IP address so that random people can talk to them.
Go generics are going to be both simple and complex (as of Go 1.18)
It's all but certain that generics will be in Go 1.18 when it's released not too far from now. I don't have strong feelings about Go having generics, or about the design that people settled on; the current design strikes me as boring, which I feel is a good thing (and which has been the case since the iteration of the 'contracts' design). But boring doesn't mean straightforward, as we've seen in other aspects of Go's design, such as addressability.
So far, basic use of Go's generics seems pretty straightforward and
simple. The syntax is reasonably obvious and memorable for simple
examples, and the standard constraints
package
will take both the drudgery and some of the errors out of writing
generics that accept only restricted sorts of types, like 'all
integers' or 'all numbers'. I can even imagine using basic generics
in my own code, although I'm not sure that that's a smart idea.
The current Gotip playground is a nice place to play around with
this simple usage.
(A few times I've found myself implementing basic operations repeatedly for full maps and 'maps as sets' that only vary slightly in their types, and maybe a bit in their usage. Generic-izing what is almost cut and paste code is at least superficially tempting, although it may actually be a sign of deeper issues in my code.)
At the same time, the current way of doing generics (also) is not simple. For example, I've tried to read and follow various iterations of the generics design, and there are things the current one says that I certainly don't understand. Some of the implications of requirements and constraints in the design are clearly tricky, in the same way that the corners of addressability are. For another illustration of this, Jaana Dogan's Generics facilitators in Go discusses something obvious you can't do in this version of Go generics and how to get around it. The official generics proposal does discuss this issue, but it gets condensed to a small paragraph:
Although methods of a generic type may use the type's parameters, methods may not themselves have additional type parameters. Where it would be useful to add type arguments to a method, people will have to write a suitably parameterized top-level function.
I expect there to be things that take people a while to really learn and understand in practice, for example this example of type inference. The whole issues section points out various minefields in the process of talking about things the current proposal doesn't deal with.
Using powerful generics is also somewhat complex, as we can see in one of the proposal's examples. Figuring out that sort of deep, interlinked generics design is a skill that's going to take people time to learn.
(This sort of elaborates on a tweet of mine looking forward to people's explainers of generics when 1.18 is released.)
PS: One area of quiet complexity is what it means in practice to put various types of things into an interface type used as a type constraint. I don't think the proposal talks much about this specifically, but see eg Embedded type parameter methods and Composite types in constraints.