| utfs-1.955/pretocol.c | | utfs-1.958/pretocol.c |
| 7 | * All rights reserved | 7 | * All rights reserved |
| 8 | * | 8 | * |
| 9 | * Created: Sun Aug 26 19:08:59 EEST 2007 too | 9 | * Created: Sun Aug 26 19:08:59 EEST 2007 too |
| 10 | * Last modified: Tue 31 Aug 2010 16:38:44 EEST too | 10 | * Last modified: Sat 02 Oct 2010 13:50:36 EEST too |
| 11 | */ | 11 | */ |
| 12 | | 12 | |
| 13 | #include <unistd.h> | 13 | #include <unistd.h> |
| 66 | #endif | 66 | #endif |
| 67 | } | 67 | } |
| 68 | | 68 | |
| | 69 | /* In case eof (or read error) happens before initial secret read |
| | 70 | * return 0 (so that in case of connect, retry). pollread() may |
| | 71 | * still make this to fail (as it should be). |
| | 72 | */ |
| 69 | | 73 | |
| 70 | int readwt(sockfd fd, unsigned char * buf, int len, int timeout) | 74 | int readwt(sockfd fd, unsigned char * buf, int len, int timeout) |
| 71 | { | 75 | { |
| 72 | int i; | 76 | int i; |
| 73 | pollread(fd, timeout); | 77 | pollread(fd, timeout); |
| 74 | i = sockread(fd, buf, len); | 78 | i = sockread(fd, buf, len); |
| 75 | if (i <= 0) | 79 | if (i <= 0) { |
| | 80 | #if 0 |
| 76 | die("%C: eof or read error"); | 81 | die("%C: eof or read error"); |
| | 82 | #else |
| | 83 | return 0; } |
| 77 | | 84 | |
| 78 | #if 0 /* d1(()) */ | 85 | #if 0 /* d1(()) */ |
| 79 | {int j; for (j = 0; j < i; j++) printf("%02x ", buf[j]); puts("");} | 86 | {int j; for (j = 0; j < i; j++) printf("%02x ", buf[j]); puts("");} |
| 101 | return sd; | 108 | return sd; |
| 102 | } | 109 | } |
| 103 | | 110 | |
| 104 | void doweaksecretexchange(const unsigned char * secrets, | 111 | int doweaksecretexchange(const unsigned char * secrets, |
| 105 | sockfd sd_in, sockfd sd_out) | 112 | sockfd sd_in, sockfd sd_out) |
| 106 | { | 113 | { |
| 107 | unsigned char * p; | 114 | unsigned char * p; |
| 119 | (void)sockwrite(sd_out, secrets, 4); | 126 | (void)sockwrite(sd_out, secrets, 4); |
| 120 | | 127 | |
| 121 | for (p = buf, i = sizeof buf; i; p += l, i -= l) | 128 | for (p = buf, i = sizeof buf; i; p += l, i -= l) |
| 122 | l = readwt(sd_in, p, i, 10 * 1000); | 129 | if ((l = readwt(sd_in, p, i, 10 * 1000)) == 0) |
| | 130 | return 0; |
| 123 | | 131 | |
| 124 | if (memcmp(buf, secrets + 4, 4) != 0) | 132 | if (memcmp(buf, secrets + 4, 4) != 0) |
| 125 | die("%C: Secret mismatch"); | 133 | die("%C: Secret mismatch"); |
| 128 | readwt(sd_in, buf, 1, 10 * 1000); | 136 | readwt(sd_in, buf, 1, 10 * 1000); |
| 129 | if (buf[0] != 0) | 137 | if (buf[0] != 0) |
| 130 | die("%C: Peer did not accept our secret -- actually junk in stream"); | 138 | die("%C: Peer did not accept our secret -- actually junk in stream"); |
| | 139 | return 1; |
| 131 | } | 140 | } |
| 132 | | 141 | |
| 133 | /* XXX add timeout handling */ | 142 | /* XXX add timeout handling */ |
| 150 | | 159 | |
| 151 | xverbose(("%C: connect '%s' (%s)", host, inet_ntoa(addr.sin_addr))); | 160 | xverbose(("%C: connect '%s' (%s)", host, inet_ntoa(addr.sin_addr))); |
| 152 | | 161 | |
| 153 | #if WIN32 | | |
| 154 | sd = tsocket(false); | | |
| 155 | if (connect(sd, (struct sockaddr *)&addr, sizeof addr) < 0) | | |
| 156 | die("%C: connect failed:"); | | |
| 157 | #else | | |
| 158 | for (i = 0;; i++) { | 162 | for (i = 0;; i++) { |
| 159 | sd = tsocket(false); | 163 | sd = tsocket(false); |
| 160 | if (connect(sd, (struct sockaddr *)&addr, sizeof addr) < 0) { | 164 | if (connect(sd, (struct sockaddr *)&addr, sizeof addr) < 0) { |
| | 165 | #if WIN32 |
| | 166 | if (i >= 5 || WSAGetLastError() != WSAECONNREFUSED) |
| | 167 | die("%C: connect failed:"); |
| | 168 | #define sleep(s) Sleep(s * 1000) |
| | 169 | #else |
| 161 | if (i >= 5 || errno != ECONNREFUSED) | 170 | if (i >= 5 || errno != ECONNREFUSED) |
| 162 | die("%C: connect failed:"); | 171 | die("%C: connect failed:"); |
| | 172 | #endif |
| 163 | close(sd); | 173 | close(sd); |
| 164 | sleep(1); | 174 | sleep(1); |
| 165 | continue; | 175 | continue; |
| 166 | } | 176 | } |
| 167 | break; | | |
| 168 | } | | |
| 169 | #endif | | |
| 170 | doweaksecretexchange(secrets, sd, sd); | 177 | if (doweaksecretexchange(secrets, sd, sd)) |
| | 178 | break; |
| | 179 | } |
| | 180 | #endif |
| 171 | return sd; | 181 | return sd; |
| 172 | } | 182 | } |
| 173 | | 183 | |
| 175 | | 185 | |
| 176 | sockfd dobindandlisten(const char * ip, int port, bool fatal) | 186 | sockfd dobindandlisten(const char * ip, int port, bool fatal) |
| 177 | { | 187 | { |
| 178 | die("%C: listening socket not supported in this version\n"); | 188 | die("%C: listening socket not supported in this version"); |
| 179 | } | 189 | } |
| 180 | inline sockfd doaccept(const unsigned char * secrets, sockfd ssd) | 190 | inline sockfd doaccept(const unsigned char * secrets, sockfd ssd) |
| 181 | { | 191 | { |
| 236 | setsockopt(sd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof one); | 246 | setsockopt(sd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof one); |
| 237 | | 247 | |
| 238 | sockclose(ssd); | 248 | sockclose(ssd); |
| 239 | doweaksecretexchange(secrets, sd, sd); | 249 | if (doweaksecretexchange(secrets, sd, sd)) |
| 240 | return sd; | 250 | return sd; |
| | 251 | else |
| | 252 | die("%C: eof or read error"); |
| 241 | } | 253 | } |
| 242 | #endif /* not NO_BIND_LISTEN_ACCEPT */ | 254 | #endif /* not NO_BIND_LISTEN_ACCEPT */ |
| 243 | | 255 | |