| 121 | self.noread() |
| 122 | |
| 123 | def try_connect(self): |
| 124 | if self.connect_to and self.shut_write: |
| 125 | self.noread() |
| 126 | self.connect_to = None |
| 127 | if not self.connect_to: |
| 128 | return # already connected |
| 129 | self.rsock.setblocking(False) |
| 130 | debug3('%r: trying connect to %r\n' % (self, self.connect_to)) |
| 131 | if socket.inet_aton(self.connect_to[0])[0] == '\0': |
| 132 | self.seterr(Exception("Can't connect to %r: " |
| 133 | "IP address starts with zero\n" |
| 134 | % (self.connect_to,))) |
| 135 | self.connect_to = None |
| 136 | return |
| 137 | try: |
| 138 | self.rsock.connect(self.connect_to) |
| 139 | # connected successfully (Linux) |
| 140 | self.connect_to = None |
| 141 | except socket.error, e: |
| 142 | debug3('%r: connect result: %s\n' % (self, e)) |
| 143 | if e.args[0] == errno.EINVAL: |
| 144 | # this is what happens when you call connect() on a socket |
| 145 | # that is now connected but returned EINPROGRESS last time, |
| 146 | # on BSD, on python pre-2.5.1. We need to use getsockopt() |
| 147 | # to get the "real" error. Later pythons do this |
| 148 | # automatically, so this code won't run. |
| 149 | realerr = self.rsock.getsockopt(socket.SOL_SOCKET, |
| 150 | socket.SO_ERROR) |
| 151 | e = socket.error(realerr, os.strerror(realerr)) |
| 152 | debug3('%r: fixed connect result: %s\n' % (self, e)) |
| 153 | if e.args[0] in [errno.EINPROGRESS, errno.EALREADY]: |
| 154 | pass # not connected yet |
| 155 | elif e.args[0] == 0: |
| 156 | # connected successfully (weird Linux bug?) |
| 157 | # Sometimes Linux seems to return EINVAL when it isn't |
| 158 | # invalid. This *may* be caused by a race condition |
| 159 | # between connect() and getsockopt(SO_ERROR) (ie. it |
| 160 | # finishes connecting in between the two, so there is no |
| 161 | # longer an error). However, I'm not sure of that. |
| 162 | # |
| 163 | # I did get at least one report that the problem went away |
| 164 | # when we added this, however. |
| 165 | self.connect_to = None |
| 166 | elif e.args[0] == errno.EISCONN: |
| 167 | # connected successfully (BSD) |
| 168 | self.connect_to = None |
| 169 | elif e.args[0] in NET_ERRS + [errno.EACCES, errno.EPERM]: |
| 170 | # a "normal" kind of error |
| 171 | self.connect_to = None |
| 172 | self.seterr(e) |
| 173 | else: |
| 174 | raise # error we've never heard of?! barf completely. |
| 175 | |
| 176 | def noread(self): |
| 177 | if not self.shut_read: |