As a PSA (public service announcement), I'm reporting here that updating your Yosemite system to 10.10.3 is incredibly toxic if you use WiFi.
I've seen other reports of this, and I've experienced it myself. What happened is that the update for 10.10.3 seems to have done something tragically bad to the WiFi drivers, such that it completely hammers the network to the point of making it unusable for everyone else on the network.
I have late 2013 iMac 27", and after I updated, I found that other systems started badly badly misbehaving. I blamed my ISP, and the router, because I was seeing ping times of tens of seconds!
(No, not milliseconds, seconds!!! In one case I saw responses over 64 seconds.) This was on other systems that were not upgraded. Needless to say, that basically left the network unusable.
(The behavior was cyclical -- I'd get a few tens of seconds where pings to 8.8.8.8 would be in the 20 msec range, and then it would start to jump up very quickly until maxing up around a minute or so. It would stay there for a minute or two, then rest or drop back to sane times. But only very briefly.)
This was most severe when using a 5GHz network. Switching down to 2.4GHz reduced some of the symptoms -- although still over 10 seconds to get traffic through and thoroughly unusable for a wide variety of applications.
There are reports that disabling Bluetooth may alleviate this, and also some people reported some success with clearing certain settings files. I've not tried either of these yet. Google around for the answer if you want to. For now, my iMac 27" is powered off, until I can take the chance to disrupt the network again to try these "fixes".
Apple, I'm seriously seriously disappointed here. I'm not sure at all how this testing got past you, but you need to fix this. Its absolutely criminal that applying a recommended update with security critical fixes in it should turn my computer into a DoS device for my local network. I'm shocked that several days later I've not seen a release update from Apple to fix this critical problem.
Anyway, my advice is, if possible, hold off for the update to 10.10.3. Its tragically, horribly toxic not just to the upgraded device, but probably to the entire network it sits on. I'm a little astounded that a bug in the code could hose an entire WiFi network as badly as this does -- I would have previously thought this impossible (and this was part of the reason why it took a while to diagnose this down to the computer -- I thought the ridiculous ping responses had to be a problem with my upstream provider!)
I'll post an update here if one becomes available.
Saturday, May 2, 2015
Tuesday, April 14, 2015
vtprint - blast from the past
I recently decided to have a look back at some old stuff I wrote. Blast from the past stuff. One of the things I decided to look at was the very first open source program I wrote -- something called vtprint.
vtprint is a tool that borrowed ideas stolen from the pine mail program. This comes from the days of serial dialups, and legacy (Kermit or ProComm for those who remember such things) serial connectivity over 14.4K modems. Printing a file on a remote server was hard back then; you could transfer the file using xmodem using rx(1), or its "newer" variants, rb(1) or rz(1), but this was awkward. It turns out that most physical terminals had support for an escape sequence that would start hardcopy to a locally attached printer, and another that would stop it. And indeed, many terminal emulators have the same support. (I added support for this myself to the rxvt(1) terminal emulator back in the mid 90's, so any emulators derived from rxvt inherit this support as well.)
So vtprint, which in retrospect could have been written in a few lines of shell code, is a C program. It supports configuration via a custom file called "vtprintcap", that can provide information about different $TERM values and the escape sequences they use. So for example, TVI925 terminals use a different escape sequence than VT100 or VT220 terminals.
The first version of it, 1.0, is lost in time, and was written back in 1991 or 1992 while I was working as a "Computer Consultant" (fancy name for BOFH, though I also did a lot of programming for the school's Windows 3.1 network and Novell NetWare 3.12 server) at the Haas School of Business at UC Berkeley. (I was a Chemical Engineering student there, and I flunked out in thermodynamics -- I still blame Gibbs Free Energy ΔG as a concept I never truly could get my mind around. It took a couple of years before I finally gave up fighting "hard engineering" and accepted my true calling as a software engineer.)
Anyway, I transferred to SDSU into the Computer Science department. While there, back in 1993, I updated vtprint significantly, and that is the release that lives on at SourceForge.
Today I imported that project to github. (And let me tell you, it took some hoops to do this. Apparently all the old CVS projects that were going to have converted to CVS are supposed to already have done so, because at this point even the conversion tools are mostly crufty and broken. Maybe I'll post what I did there.) Most of the files indicate an age of 11 years ago. That's because 11 years ago I imported the source into CVS for the benefit of SourceForge. The actual files date back to 1994, and you can even see my old email address -- which hasn't worked for a couple of decades, in the files.
So, I gave vtprint a whirl today for the first time in years:
Sadly, MacOS X Terminal.app does not appear to emulate the escape sequences properly. But iTerm2 does so very nicely. It even generates a nice print preview using the standard MacOS X print dialog. Sadly, it does not pass through PostScript unmolested, but for printing ASCII files it works beautifully.
I think that I'm going to start using vtprint again, when I need to print a file located on a virtual machine, or over a connection that only offers SSH (such as a secured access machine). With firewalled networks, I suspect that this program has new usefulness. I'm also switching from Terminal.app (as many people have suggested) to iTerm2.
vtprint is a tool that borrowed ideas stolen from the pine mail program. This comes from the days of serial dialups, and legacy (Kermit or ProComm for those who remember such things) serial connectivity over 14.4K modems. Printing a file on a remote server was hard back then; you could transfer the file using xmodem using rx(1), or its "newer" variants, rb(1) or rz(1), but this was awkward. It turns out that most physical terminals had support for an escape sequence that would start hardcopy to a locally attached printer, and another that would stop it. And indeed, many terminal emulators have the same support. (I added support for this myself to the rxvt(1) terminal emulator back in the mid 90's, so any emulators derived from rxvt inherit this support as well.)
So vtprint, which in retrospect could have been written in a few lines of shell code, is a C program. It supports configuration via a custom file called "vtprintcap", that can provide information about different $TERM values and the escape sequences they use. So for example, TVI925 terminals use a different escape sequence than VT100 or VT220 terminals.
The first version of it, 1.0, is lost in time, and was written back in 1991 or 1992 while I was working as a "Computer Consultant" (fancy name for BOFH, though I also did a lot of programming for the school's Windows 3.1 network and Novell NetWare 3.12 server) at the Haas School of Business at UC Berkeley. (I was a Chemical Engineering student there, and I flunked out in thermodynamics -- I still blame Gibbs Free Energy ΔG as a concept I never truly could get my mind around. It took a couple of years before I finally gave up fighting "hard engineering" and accepted my true calling as a software engineer.)
Anyway, I transferred to SDSU into the Computer Science department. While there, back in 1993, I updated vtprint significantly, and that is the release that lives on at SourceForge.
Today I imported that project to github. (And let me tell you, it took some hoops to do this. Apparently all the old CVS projects that were going to have converted to CVS are supposed to already have done so, because at this point even the conversion tools are mostly crufty and broken. Maybe I'll post what I did there.) Most of the files indicate an age of 11 years ago. That's because 11 years ago I imported the source into CVS for the benefit of SourceForge. The actual files date back to 1994, and you can even see my old email address -- which hasn't worked for a couple of decades, in the files.
So, I gave vtprint a whirl today for the first time in years:
garrett@hipster{4}> ./vtprint README
*** vtprint (v2.0.2) ***
Copyright 1993-1994, Garrett D'AmoreLast revised October 25, 1994.
NO WARRANTY! Use "vtprint -w" for info.Freely redistributable. Use "vtprint -l" for info.
vtprint: Can't open /usr/local/lib/vtprint/vtprintcap, using builtin codes.vtprint: Using <stdout> for output.vtprint: Output flags: formfeedvtprint: Printed README.vtprint: Successfully printed 1 file (1 specified).
Sadly, MacOS X Terminal.app does not appear to emulate the escape sequences properly. But iTerm2 does so very nicely. It even generates a nice print preview using the standard MacOS X print dialog. Sadly, it does not pass through PostScript unmolested, but for printing ASCII files it works beautifully.
I think that I'm going to start using vtprint again, when I need to print a file located on a virtual machine, or over a connection that only offers SSH (such as a secured access machine). With firewalled networks, I suspect that this program has new usefulness. I'm also switching from Terminal.app (as many people have suggested) to iTerm2.
Sunday, February 22, 2015
IPv6 and IPv4 name resolution with Go
As part of a work-related project, I'm writing code that needs to resolve DNS names using Go, on illumos.
While doing this work, I noticed a very surprising thing. When a host has both IPv6 and IPv4 addresses associated with a name (such as localhost), Go prefers to resolve to the IPv4 version of the name, unless one has asked specifically for v6 names.
This flies in the fact of existing practice on illumos & Solaris systems, where resolving a name tends to give an IPv6 result, assuming that any IPv6 address is plumbed on the system. (And on modern installations, that is the default -- at least the loopback interface of ::1 is always plumbed by default. And not only that, but services listening on that address will automatically serve up both v6 and v4 clients that connect on either ::1 or 127.0.0.1.)
The rationale for this logic is buried in the Go net/ipsock.go file, in comments for the function firstFavoriteAddr ():
Its kind of a sad that the Go people felt that they had to make this choice -- at some level it robs the choice from the administrator, and encourages the existing broken code to remain so. I'm not sure what the other systems use, but at least on illumos, we have a stack that understands the situation, and resolves optimally for the given the situation of the user. Sadly, Go shoves that intelligence aside, and uses its own overrides.
One moral of the story here is -- always use either explicit v4 or v6 addresses if you care, or ensure that your names resolve properly.
While doing this work, I noticed a very surprising thing. When a host has both IPv6 and IPv4 addresses associated with a name (such as localhost), Go prefers to resolve to the IPv4 version of the name, unless one has asked specifically for v6 names.
This flies in the fact of existing practice on illumos & Solaris systems, where resolving a name tends to give an IPv6 result, assuming that any IPv6 address is plumbed on the system. (And on modern installations, that is the default -- at least the loopback interface of ::1 is always plumbed by default. And not only that, but services listening on that address will automatically serve up both v6 and v4 clients that connect on either ::1 or 127.0.0.1.)
The rationale for this logic is buried in the Go net/ipsock.go file, in comments for the function firstFavoriteAddr ():
76 // We'll take any IP address, but since the dialing
77 // code does not yet try multiple addresses
78 // effectively, prefer to use an IPv4 address if
79 // possible. This is especially relevant if localhost
80 // resolves to [ipv6-localhost, ipv4-localhost]. Too
81 // much code assumes localhost == ipv4-localhost.
This is a really surprising result. If you want to get IPv6 names by default, with Go, you could use the net.ResolveIPAddr() (or ResolveTCPAddr() or ResolveUDPAddr()) functions with the network type of "ip6", "tcp6", or "udp6" first. Then if that resolution fails, you can try the standard versions, or the v4 specific versions (doing the latter is probably slightly more efficient.) Here's what that code looks like: name := "localhost"
// First we try IPv6. Note that we *hope* this fails if the host
// stack does not actually support IPv6.
err, ip := net.ResolveIP("ip6", name)
if err != nil {
// IPv6 not found, maybe IPv4?
err, ip = net.ResolveIP("ip4", name)
}
However, this choice turns out to also be evil, because while ::1 often works locally as an IPv6 address and is functional, other addresses, for example www.google.com, will resolve to IPv6 addresses which will not work unless you have a clean IPv6 path all the way through. For example, the above gives me this for www.google.com: 2607:f8b0:4007:804::1010, but if I try to telnet to it, it won't work -- no route to host (of course, because I don't have an IPv6 path to the Internet, both my home gateway and my ISP are IPv4 only.)Its kind of a sad that the Go people felt that they had to make this choice -- at some level it robs the choice from the administrator, and encourages the existing broken code to remain so. I'm not sure what the other systems use, but at least on illumos, we have a stack that understands the situation, and resolves optimally for the given the situation of the user. Sadly, Go shoves that intelligence aside, and uses its own overrides.
One moral of the story here is -- always use either explicit v4 or v6 addresses if you care, or ensure that your names resolve properly.
Wednesday, February 11, 2015
Rise of mangos
What is mangos?
Those of you who follow me may have heard about this project I've created called mangos.
Mangos is a lightweight messaging system designed to be wire compatible with nanomsg, but is implemented entirely in Go.
There is a very nice write up of mangos by Tyler Treat, which might help explain some things.
Recent Activity
First off, there was Tyler's excellent article. (By the way, he's done a series comparing and contrasting other messaging systems -- highly recommended reading.)
Second, mangos got mentioned on Hacker News. That drew a large number visitors to my github repo.
Then another open source project, Goq, switched from using libnanomsg to mangos, using the compatibility shim I provided for such use. As a consequence of that work, several bugs were identified, and subsequently squashed.
The upshot of all that is that I saw the number unique visitors sky rocket. On Saturday Feb 7, there were over 2500 unique visitors to the github page, and 29 unique people took clones. Sunday it tapered sharply to just over 1k visitors, and today there were only 7. Peaks rarely get sharper than that.
Improvements
Over the past week or so I've made a large number of changes and improvements. Recently, mangos has grown support for RFC 6455 (websocket), including websocket over TLS, and has had numerous internal improvements.
Some of these changes have broken API. If you use mangos, I'm sorry about the breakage -- please let me know if you're hurt by this. (I have created tagged releases for v1.0.0 and v1.1.0 in an attempt to mitigate the risk, but tip still has some interesting changes in it.)
Unlike libnanomsg, mangos (tip only) can notify you when a connection is added or removed, and you can access interesting information about the connection. This is in the Port API.
Futures
We are using mangos internally at Lucera, and I know now of several cases of production use. This is kind of scary at one level, since I wrote this originally as a hobby project about a year ago (to learn Go.) But it has become useful -- frankly extending mangos is far far more pleasurable than working in the C libnanomsg implementation -- a lot of this is thanks to Go which is utterly pleasurable to work in (no matter how bad the guts may be reputed to be). Being able to write a new TLS transport, or even websocket, in the course of an afternoon or two (actually for TLS it was more like an hour), is really nice.
I'm hoping that more people will find it useful, and that folks who want to experiment with the underlying messaging patterns may find it easier to work with than the C code. Ideally, there will be more collaborators here, as we start exploring new directions for this stuff.
In the meantime, I'm going to continue to work to improve and extend mangos, because its become one of the tools at my day job. Its nice when work and pleasure come together!
Subscribe to:
Posts (Atom)
