18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
** This file manages low-level client socket communications. The socket
** might be for a simple HTTP request or for an encrypted HTTPS request.
**
** This file implements a singleton. A single client socket may be active
** at a time. State information is stored in static variables. The identity
** of the server is held in global variables that are set by url_parse().
**
** Low-level sockets are abstracted out into this module because they
** are handled different on Unix and windows.
*/
#include "config.h"
#include "http_socket.h"
#if defined(_WIN32)
# include <winsock2.h>
|
|
|
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
** This file manages low-level client socket communications. The socket
** might be for a simple HTTP request or for an encrypted HTTPS request.
**
** This file implements a singleton. A single client socket may be active
** at a time. State information is stored in static variables. The identity
** of the server is held in global variables that are set by url_parse().
**
** Low-level sockets are abstracted out into this module because they
** are handled different on Unix and windows.
*/
#include "config.h"
#include "http_socket.h"
#if defined(_WIN32)
# include <winsock2.h>
|
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
free(socketErrMsg);
socketErrMsg = 0;
}
/*
** Set the socket error message.
*/
void socket_set_errmsg(char *zFormat, ...){
va_list ap;
socket_clear_errmsg();
va_start(ap, zFormat);
socketErrMsg = vmprintf(zFormat, ap);
va_end(ap);
}
|
|
|
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
free(socketErrMsg);
socketErrMsg = 0;
}
/*
** Set the socket error message.
*/
void socket_set_errmsg(const char *zFormat, ...){
va_list ap;
socket_clear_errmsg();
va_start(ap, zFormat);
socketErrMsg = vmprintf(zFormat, ap);
va_end(ap);
}
|
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
#endif
iSocket = -1;
}
}
/*
** Open a socket connection. The identify of the server is determined
** by global variables that are set using url_parse():
**
** g.urlName Name of the server. Ex: www.fossil-scm.org
** g.urlPort TCP/IP port to use. Ex: 80
**
** Return the number of errors.
*/
int socket_open(UrlData *pUrlData){
int error = 0;
#ifdef HAVE_GETADDRINFO
struct addrinfo hints;
|
|
|
|
|
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
#endif
iSocket = -1;
}
}
/*
** Open a socket connection. The identify of the server is determined
** by pUrlData
**
** pUrlDAta->name Name of the server. Ex: www.fossil-scm.org
** pUrlDAta->port TCP/IP port to use. Ex: 80
**
** Return the number of errors.
*/
int socket_open(UrlData *pUrlData){
int error = 0;
#ifdef HAVE_GETADDRINFO
struct addrinfo hints;
|
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
hints.ai_family = PF_UNSPEC;
#else
hints.ai_family = PF_INET;
#endif
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
sPort = mprintf("%d", g.urlPort);
if(getaddrinfo(g.urlName, sPort, &hints, &res)) {
socket_set_errmsg("can't resolve host name: %s", g.urlName);
free(sPort);
return 1;
}
for(i = res; i; i = i->ai_next) {
iSocket = socket(i->ai_family, i->ai_socktype, i->ai_protocol);
if(iSocket < 0) {
continue;
}
if(connect(iSocket, i->ai_addr, i->ai_addrlen) < 0) {
close(iSocket);
iSocket = -1;
continue;
}
if(!getnameinfo(i->ai_addr, i->ai_addrlen, ip, sizeof(ip),
NULL, 0, NI_NUMERICHOST))
g.zIpAddr = mprintf("%s", ip);
break;
}
if(iSocket == -1) {
socket_set_errmsg("cannot connect to host %s:%s", g.urlName, sPort);
error = 1;
}
free(sPort);
freeaddrinfo(res);
#else
static struct sockaddr_in addr; /* The server address */
static int addrIsInit = 0; /* True once addr is initialized */
|
|
|
|
|
|
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
hints.ai_family = PF_UNSPEC;
#else
hints.ai_family = PF_INET;
#endif
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
sPort = mprintf("%d", pUrlData->port);
if(getaddrinfo(pUrlData->name, sPort, &hints, &res)) {
socket_set_errmsg("can't resolve host name: %s", pUrlData->name);
free(sPort);
return 1;
}
for(i = res; i; i = i->ai_next) {
iSocket = socket(i->ai_family, i->ai_socktype, i->ai_protocol);
if(iSocket < 0) {
continue;
}
if(connect(iSocket, i->ai_addr, i->ai_addrlen) < 0) {
close(iSocket);
iSocket = -1;
continue;
}
if(!getnameinfo(i->ai_addr, i->ai_addrlen, ip, sizeof(ip),
NULL, 0, NI_NUMERICHOST))
g.zIpAddr = mprintf("%s", ip);
break;
}
if(iSocket == -1) {
socket_set_errmsg("cannot connect to host %s:%s", pUrlData->name, sPort);
error = 1;
}
free(sPort);
freeaddrinfo(res);
#else
static struct sockaddr_in addr; /* The server address */
static int addrIsInit = 0; /* True once addr is initialized */
|
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
|
N -= (size_t)got;
pContent = (void*)&((char*)pContent)[got];
}
return total;
}
/*
** Attempt to resolve g.urlName to IP and setup g.zIpAddr so rcvfrom gets
** populated. For hostnames with more than one IP (or if overridden in
** ~/.ssh/config) the rcvfrom may not match the host to which we connect.
*/
void socket_ssh_resolve_addr(UrlData *pUrlData){
struct hostent *pHost; /* Used to make best effort for rcvfrom */
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
pHost = gethostbyname(pUrlData->name);
if( pHost!=0 ){
memcpy(&addr.sin_addr,pHost->h_addr_list[0],pHost->h_length);
g.zIpAddr = mprintf("%s", inet_ntoa(addr.sin_addr));
}
}
|
|
|
|
>
|
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
|
N -= (size_t)got;
pContent = (void*)&((char*)pContent)[got];
}
return total;
}
/*
** Attempt to resolve pUrlData->name to an IP address and setup g.zIpAddr
** so rcvfrom gets populated. For hostnames with more than one IP (or
** if overridden in ~/.ssh/config) the rcvfrom may not match the host
** to which we connect.
*/
void socket_ssh_resolve_addr(UrlData *pUrlData){
struct hostent *pHost; /* Used to make best effort for rcvfrom */
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
pHost = gethostbyname(pUrlData->name);
if( pHost!=0 ){
memcpy(&addr.sin_addr,pHost->h_addr_list[0],pHost->h_length);
g.zIpAddr = mprintf("%s", inet_ntoa(addr.sin_addr));
}
}
|