00001 #include "log.h"
00002 #include "socket.h"
00003 #include "client.h"
00004 #include "collection.h"
00005
00006 #include <stdio.h>
00007 #include <stdlib.h>
00008 #include <string.h>
00009 #include <errno.h>
00010
00011 #include <sys/types.h>
00012
00013 #if defined(unix) || defined(__unix__) || defined(__MACH__)
00014 #include <unistd.h>
00015 #include <sys/socket.h>
00016 #include <netinet/in.h>
00017 #include <arpa/inet.h>
00018 #include <netdb.h>
00019 #endif
00020
00021 #ifdef CP_USE_SSL
00022 #include <openssl/ssl.h>
00023 #include <openssl/err.h>
00024
00025 #ifdef _WINDOWS
00026 #include <wincrypt.h>
00027 #endif
00028
00029 #endif
00030
00031 #ifdef CP_HAS_STRINGS_H
00032 #include <strings.h>
00033 #else
00034 #include "util.h"
00035 #endif
00036
00037 #ifdef _WINDOWS
00038 #include <Winsock2.h>
00039 #include <Ws2tcpip.h>
00040 #include <WS2SPI.H>
00041 #endif
00042
00043 #ifdef CP_USE_SSL
00044
00045 char *ssl_verification_error_str(int code)
00046 {
00047 switch (code)
00048 {
00049 case X509_V_OK:
00050 return "X509_V_OK the operation was successful.";
00051
00052 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
00053 return
00054 "X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT the issuer certificate could "
00055 "not be found";
00056
00057 case X509_V_ERR_UNABLE_TO_GET_CRL:
00058 return
00059 "X509_V_ERR_UNABLE_TO_GET_CRL the CRL of a certificate could "
00060 "not be found.";
00061
00062 case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
00063 return
00064 "X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE the certificate signature"
00065 " could not be decrypted.";
00066
00067 case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
00068 return
00069 "X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE the CRL signature could "
00070 "not be decrypted";
00071
00072 case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
00073 return
00074 "X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY the public key in the "
00075 "certificate SubjectPublicKeyInfo could not be read.";
00076
00077 case X509_V_ERR_CERT_SIGNATURE_FAILURE:
00078 return
00079 "X509_V_ERR_CERT_SIGNATURE_FAILURE the signature of the certificate "
00080 "is invalid.";
00081
00082 case X509_V_ERR_CRL_SIGNATURE_FAILURE:
00083 return
00084 "X509_V_ERR_CRL_SIGNATURE_FAILURE the signature of the "
00085 " certificate is invalid.";
00086
00087 case X509_V_ERR_CERT_NOT_YET_VALID:
00088 return
00089 "X509_V_ERR_CERT_NOT_YET_VALID the certificate is not yet valid: the "
00090 " notBefore date is after the current time.";
00091
00092 case X509_V_ERR_CERT_HAS_EXPIRED:
00093 return
00094 "X509_V_ERR_CERT_HAS_EXPIRED the certificate has expired: the "
00095 "notAfter date is before the current time.";
00096
00097 case X509_V_ERR_CRL_NOT_YET_VALID:
00098 return "X509_V_ERR_CRL_NOT_YET_VALID the CRL is not yet valid.";
00099
00100 case X509_V_ERR_CRL_HAS_EXPIRED:
00101 return "X509_V_ERR_CRL_HAS_EXPIRED the CRL has expired.";
00102
00103 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
00104 return
00105 "X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD the certificate notBefore "
00106 "field contains an invalid time.";
00107
00108 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
00109 return
00110 "X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD the certificate notAfter "
00111 "field contains an invalid time.";
00112
00113 case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
00114 return
00115 "X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD the CRL lastUpdate field "
00116 "contains an invalid time.";
00117
00118 case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
00119 return
00120 "X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD the CRL nextUpdate field "
00121 "contains an invalid time.";
00122
00123 case X509_V_ERR_OUT_OF_MEM:
00124 return
00125 "X509_V_ERR_OUT_OF_MEM an error occurred trying to allocate memory.";
00126
00127 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
00128 return
00129 "X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT the passed certificate is self"
00130 " signed and the same certificate cannot be found in the list of "
00131 "trusted certificates.";
00132
00133 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
00134 return
00135 "X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN the certificate chain could be "
00136 "built up using the untrusted certificates but the root could not be "
00137 "found locally.";
00138
00139 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
00140 return
00141 "X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY the issuer certificate "
00142 "of a locally looked up certificate could not be found.";
00143
00144 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
00145 return
00146 "X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE no signatures could be "
00147 "verified because the chain contains only one certificate and it is "
00148 "not self signed.";
00149
00150 case X509_V_ERR_CERT_CHAIN_TOO_LONG:
00151 return
00152 "X509_V_ERR_CERT_CHAIN_TOO_LONG the certificate chain length is "
00153 "greater than the supplied maximum depth.";
00154
00155 case X509_V_ERR_CERT_REVOKED:
00156 return
00157 "X509_V_ERR_CERT_REVOKED the certificate has been revoked.";
00158
00159 case X509_V_ERR_INVALID_CA:
00160 return
00161 "X509_V_ERR_INVALID_CA a CA certificate is invalid. Either it is not a"
00162 " CA or its extensions are not consistent with the supplied purpose.";
00163
00164 case X509_V_ERR_PATH_LENGTH_EXCEEDED:
00165 return
00166 "X509_V_ERR_PATH_LENGTH_EXCEEDED the basicConstraints pathlength "
00167 "parameter has been exceeded.";
00168
00169 case X509_V_ERR_INVALID_PURPOSE:
00170 return
00171 "X509_V_ERR_INVALID_PURPOSE the supplied certificate cannot be used "
00172 "for the specified purpose.";
00173
00174 case X509_V_ERR_CERT_UNTRUSTED:
00175 return
00176 "X509_V_ERR_CERT_UNTRUSTED the root CA is not marked as trusted for "
00177 "the specified purpose.";
00178
00179 case X509_V_ERR_CERT_REJECTED:
00180 return
00181 "X509_V_ERR_CERT_REJECTED the root CA is marked to reject the "
00182 "specified purpose.";
00183
00184 case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
00185 return
00186 "X509_V_ERR_SUBJECT_ISSUER_MISMATCH the current candidate issuer "
00187 "certificate was rejected because its subject name did not match the "
00188 "issuer name of the current certificate.";
00189
00190 case X509_V_ERR_AKID_SKID_MISMATCH:
00191 return
00192 "X509_V_ERR_AKID_SKID_MISMATCH the current candidate issuer certificate"
00193 " was rejected because its subject key identifier was present and did "
00194 "not match the authority key identifier of the current certificate.";
00195
00196 case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
00197 return
00198 "X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH the current candidate issuer "
00199 "certificate was rejected because its"
00200 " issuer name and serial number was present and did not match the"
00201 " authority key identifier of the current certificate. Only displayed"
00202 " when the -issuer_checks option is set.";
00203
00204 case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
00205 return
00206 "X509_V_ERR_KEYUSAGE_NO_CERTSIGN the current candidate issuer "
00207 "certificate was rejected because its"
00208 " keyUsage extension does not permit certificate signing.";
00209
00210 case X509_V_ERR_APPLICATION_VERIFICATION:
00211 return
00212 "X509_V_ERR_APPLICATION_VERIFICATION "
00213 "server presented no certificate";
00214 }
00215
00216 return "unknown verification error";
00217 }
00218
00219 char *ssl_err_inf(int err)
00220 {
00221 switch (err)
00222 {
00223 case SSL_ERROR_NONE: return "SSL_ERROR_NONE"; break;
00224 case SSL_ERROR_ZERO_RETURN: return "SSL_ERROR_ZERO_RETURN"; break;
00225 case SSL_ERROR_WANT_READ: return "SSL_ERROR_WANT_READ"; break;
00226 case SSL_ERROR_WANT_WRITE: return "SSL_ERROR_WANT_WRITE"; break;
00227 case SSL_ERROR_WANT_CONNECT: return "SSL_ERROR_WANT_CONNECT"; break;
00228 #ifdef SSL_ERROR_WANT_ACCEPT
00229 case SSL_ERROR_WANT_ACCEPT: return "SSL_ERROR_WANT_ACCEPT"; break;
00230 #endif
00231 case SSL_ERROR_WANT_X509_LOOKUP: return "SSL_ERROR_WANT_X509_LOOKUP"; break;
00232 case SSL_ERROR_SYSCALL: return "SSL_ERROR_SYSCALL"; break;
00233 case SSL_ERROR_SSL: return "SSL_ERROR_SSL"; break;
00234 }
00235
00236 return "unknown";
00237 }
00238
00239 void cp_client_ssl_init()
00240 {
00241 cp_socket_ssl_init();
00242 }
00243
00244 void cp_client_ssl_shutdown()
00245 {
00246 cp_socket_ssl_shutdown();
00247 }
00248
00249 #endif
00250
00251 #ifndef CP_HAS_GETHOSTBYNAME_R_6
00252 static cp_lock *cp_gethostbyname_lock = NULL;
00253 #endif
00254
00255 void cp_client_init()
00256 {
00257 #ifndef CP_HAS_GETHOSTBYNAME_R_6
00258 if (cp_gethostbyname_lock == NULL)
00259 {
00260 cp_gethostbyname_lock = (cp_lock *) calloc(1, sizeof(cp_lock));
00261 if (cp_gethostbyname_lock == NULL)
00262 cp_fatal(CP_MEMORY_ALLOCATION_FAILURE, "can\'t allocate lock");
00263
00264 if (cp_lock_init(cp_gethostbyname_lock, NULL))
00265 cp_fatal(CP_INITIALIZATION_FAILURE, "can\'t initialize lock");
00266 }
00267 #endif
00268 cp_socket_init();
00269 }
00270
00271 void cp_client_shutdown()
00272 {
00273 #ifndef CP_HAS_GETHOSTBYNAME_R_6
00274 if (cp_gethostbyname_lock != NULL)
00275 {
00276 cp_lock_destroy(cp_gethostbyname_lock);
00277 free(cp_gethostbyname_lock);
00278 cp_gethostbyname_lock = NULL;
00279 }
00280 #endif
00281 cp_socket_shutdown();
00282 }
00283
00284 static void delete_hostent(struct hostent *hp)
00285 {
00286 if (hp)
00287 {
00288 #ifndef CP_HAS_GETHOSTBYNAME_R_6
00289 int i;
00290
00291 if (hp->h_name) free(hp->h_name);
00292
00293 if (hp->h_aliases)
00294 {
00295 for (i = 0; hp->h_aliases[i]; i++)
00296 free(hp->h_aliases[i]);
00297 free(hp->h_aliases);
00298 }
00299
00300 if (hp->h_addr_list)
00301 {
00302 for (i = 0; hp->h_addr_list[i]; i++)
00303 free(hp->h_addr_list[i]);
00304 free(hp->h_addr_list);
00305 }
00306 #endif
00307
00308 free(hp);
00309 }
00310 }
00311
00312 #ifdef CP_HAS_GETHOSTBYNAME_R_6
00313 #define RESOLVE_BUFLEN 0x1000
00314 static int resolve_addr(cp_client *client)
00315 {
00316 struct hostent *res = (struct hostent *) calloc(1, sizeof(struct hostent));
00317 struct hostent *result;
00318 char buf[RESOLVE_BUFLEN];
00319 int rc, err;
00320
00321 rc = gethostbyname_r(client->host, res, buf, RESOLVE_BUFLEN, &result, &err);
00322 if (!(rc == 0 && result != NULL && err == 0))
00323 {
00324 free(res);
00325 rc = -1;
00326 }
00327 else
00328 client->hostspec = res;
00329
00330 return rc;
00331 }
00332
00333 #else
00334
00335 struct hostent *hostentdup(struct hostent *src)
00336 {
00337 int i, count;
00338 struct hostent *dup = (struct hostent *) calloc(1, sizeof(struct hostent));
00339 if (src->h_name) dup->h_name = strdup(src->h_name);
00340 for (count = 0; src->h_aliases[count] != NULL; count++);
00341 dup->h_aliases = (char **) calloc(count + 1, sizeof(char *));
00342 if (count)
00343 {
00344 for (i = 0; i < count; i++)
00345 dup->h_aliases[i] = strdup(src->h_aliases[i]);
00346 }
00347 dup->h_aliases[count] = NULL;
00348 dup->h_addrtype = src->h_addrtype;
00349 dup->h_length = src->h_length;
00350 for (count = 0; src->h_addr_list[count] != NULL; count++);
00351 dup->h_addr_list = (char **) calloc(count + 1, sizeof(char *));
00352 if (count)
00353 {
00354 for (i = 0; i < count; i++)
00355 {
00356 dup->h_addr_list[i] = (char *) malloc(src->h_length);
00357 memcpy(dup->h_addr_list[i], src->h_addr_list[i], src->h_length);
00358 }
00359 }
00360 dup->h_addr_list[count] = NULL;
00361
00362 return dup;
00363 }
00364
00365 void print_addr(struct hostent *hp)
00366 {
00367 int i;
00368
00369 printf("host %s: ", hp->h_name);
00370 for (i = 0; hp->h_addr_list[i] != NULL; i++)
00371 printf("addr[%d]: %s\n", i, inet_ntoa(*(struct in_addr *) hp->h_addr_list[i]));
00372 }
00373
00374 static int resolve_addr(cp_client *sock)
00375 {
00376 int rc = 0;
00377 struct hostent* phostent;
00378
00379 if ((rc = cp_lock_wrlock(cp_gethostbyname_lock)) != 0) return -1;
00380 phostent = gethostbyname(sock->host);
00381
00382 if (phostent)
00383 {
00384 sock->hostspec = hostentdup(phostent);
00385 rc = 0;
00386 }
00387
00388 cp_lock_unlock(cp_gethostbyname_lock);
00389
00390 return rc;
00391 }
00392
00393 #endif
00394
00395
00396 cp_client *cp_client_create(char *host, int port)
00397 {
00398 cp_client *client = calloc(1, sizeof(cp_client));
00399 if (client == NULL) return NULL;
00400
00401 client->retry = DEFAULT_RETRIES;
00402 client->host = strdup(host);
00403 client->port = port;
00404
00405 if ((resolve_addr(client)))
00406 {
00407 cp_client_destroy(client);
00408 return NULL;
00409 }
00410
00411 client->fd = socket(PF_INET, SOCK_STREAM, 0);
00412 if (client->fd == -1)
00413 {
00414 cp_perror(CP_IO_ERROR, errno, "can\'t create socket");
00415 cp_client_destroy(client);
00416 return NULL;
00417 }
00418
00419 return client;
00420 }
00421
00422 #ifdef CP_USE_SSL
00423 cp_client *cp_client_create_ssl(char *host,
00424 int port,
00425 char *CA_file,
00426 char *CA_path,
00427 int verification_mode)
00428 {
00429 cp_client *client = cp_client_create(host, port);
00430 if (client == NULL) return NULL;
00431
00432 client->ctx = get_client_ssl_ctx(CA_file, CA_path);
00433 if (client->ctx == NULL)
00434 {
00435 cp_client_destroy(client);
00436 return NULL;
00437 }
00438
00439 SSL_CTX_set_verify(client->ctx, verification_mode, NULL);
00440 SSL_CTX_set_mode(client->ctx, SSL_MODE_AUTO_RETRY);
00441
00442 client->use_ssl = 1;
00443 client->ssl = SSL_new(client->ctx);
00444 SSL_set_fd(client->ssl, client->fd);
00445
00446 return client;
00447 }
00448 #endif
00449
00450 int cp_client_reopen(cp_client *client, char *host, int port)
00451 {
00452 cp_client_close(client);
00453
00454 if (client->host)
00455 {
00456 free(client->host);
00457 client->host = NULL;
00458 }
00459 if (client->hostspec)
00460 {
00461 delete_hostent(client->hostspec);
00462 client->hostspec = NULL;
00463 }
00464
00465 if (client->addr)
00466 {
00467 free(client->addr);
00468 client->addr = NULL;
00469 }
00470
00471 client->host = strdup(host);
00472 client->port = port;
00473
00474 if ((resolve_addr(client)))
00475 {
00476 cp_error(CP_IO_ERROR, "can\'t resolve address for %s", host);
00477 return -1;
00478 }
00479
00480 client->fd = socket(PF_INET, SOCK_STREAM, 0);
00481 if (client->fd == -1)
00482 {
00483 cp_perror(CP_IO_ERROR, errno, "can\'t create socket");
00484 return -1;
00485 }
00486
00487 #ifdef CP_USE_SSL
00488 if (client->use_ssl)
00489 SSL_set_fd(client->ssl, client->fd);
00490 #endif
00491
00492 return cp_client_connect(client);
00493 }
00494
00496 cp_client *cp_client_create_addr(struct sockaddr_in *addr)
00497 {
00498 cp_client *client = calloc(1, sizeof(cp_client));
00499 if (client == NULL) return NULL;
00500
00501 client->retry = DEFAULT_RETRIES;
00502 client->addr = malloc(sizeof(struct sockaddr_in));
00503 if (client->addr == NULL)
00504 {
00505 free(client);
00506 return NULL;
00507 }
00508 *client->addr = *addr;
00509
00510 return client;
00511 }
00512
00514 void cp_client_set_timeout(cp_client *client, int sec, int usec)
00515 {
00516 client->timeout.tv_sec = sec;
00517 client->timeout.tv_usec = usec;
00518 }
00519
00521 void cp_client_set_retry(cp_client *client, int retry_count)
00522 {
00523 client->retry = retry_count;
00524 }
00525
00527 void cp_client_set_owner(cp_client *client, void *owner)
00528 {
00529 client->owner = owner;
00530 }
00531
00532 #ifdef CP_USE_SSL
00533 int cp_client_connect_ssl(cp_client *client)
00534 {
00535 int rc = SSL_connect(client->ssl);
00536 if (rc <= 0)
00537 {
00538 int err = SSL_get_error(client->ssl, rc);
00539 const char *reason = ERR_reason_error_string(err);
00540
00541 cp_error(CP_SSL_HANDSHAKE_FAILED, "can\'t connect to %s: %s",
00542 inet_ntoa(client->addr->sin_addr),
00543 reason ? reason : ssl_err_inf(err));
00544 if (rc == 0) rc = -1;
00545 }
00546 else
00547 {
00548 client->server_certificate = SSL_get_peer_certificate(client->ssl);
00549
00550 if (client->server_certificate == NULL)
00551 {
00552 cp_error(CP_SSL_VERIFICATION_ERROR,
00553 "connecting to %s: server presented no certificate",
00554 inet_ntoa(client->addr->sin_addr));
00555
00556
00557 return X509_V_ERR_APPLICATION_VERIFICATION;
00558 }
00559 if ((rc = SSL_get_verify_result(client->ssl)) != X509_V_OK)
00560 {
00561 cp_error(CP_SSL_VERIFICATION_ERROR,
00562 "SSL_get_verify_result: %d\n", rc);
00563 return rc;
00564 }
00565 }
00566
00567 return rc;
00568 }
00569 #endif
00570
00572 int cp_client_connect(cp_client *client)
00573 {
00574 struct sockaddr_in addr;
00575 int rc = 0;
00576 int connected = 0;
00577 int retry = client->retry;
00578
00579 if (client->addr == NULL && client->hostspec == NULL)
00580 {
00581 cp_error(CP_INITIALIZATION_FAILURE, "client socket not initialized");
00582 return CP_INITIALIZATION_FAILURE;
00583 }
00584
00585 memset(&addr, 0, sizeof(struct sockaddr_in));
00586 addr.sin_family = client->hostspec->h_addrtype;
00587 addr.sin_port = htons(client->port);
00588
00589 while (!connected && retry--)
00590 {
00591 if (client->addr)
00592 {
00593 rc = connect(client->fd, (struct sockaddr *) client->addr,
00594 sizeof(struct sockaddr_in));
00595 if (rc == 0)
00596 {
00597 connected = 1;
00598 break;
00599 }
00600 }
00601
00602 if (client->hostspec)
00603 {
00604 int i;
00605
00606 for (i = 0; client->hostspec->h_addr_list[i] != NULL; i++)
00607 {
00608 addr.sin_addr =
00609 *((struct in_addr *) client->hostspec->h_addr_list[i]);
00610 rc = connect(client->fd, (struct sockaddr *) &addr,
00611 sizeof(struct sockaddr_in));
00612 if (rc == 0)
00613 {
00614 if (client->addr == NULL)
00615 {
00616 client->addr =
00617 (struct sockaddr_in *) malloc(sizeof(struct sockaddr_in));
00618 }
00619 if (client->addr == NULL)
00620 cp_error(CP_MEMORY_ALLOCATION_FAILURE, "can\'t allocate address storage memory");
00621 else
00622 memcpy(client->addr, &addr, sizeof(struct sockaddr_in));
00623
00624 connected = 1;
00625 break;
00626 }
00627 }
00628 }
00629 }
00630
00631 #ifdef CP_USE_SSL
00632 if (client->use_ssl && connected)
00633 rc = cp_client_connect_ssl(client);
00634 #endif
00635
00636 if (connected && rc == 0)
00637 gettimeofday(&client->created, NULL);
00638
00639 return rc;
00640 }
00641
00642
00643 #ifdef CP_USE_SSL
00644 int verify_host_name(X509 *cert, char *host)
00645 {
00646 char buf[0x100];
00647 X509_NAME *name = X509_get_subject_name(cert);
00648 X509_NAME_get_text_by_NID(name, NID_commonName, buf, 0x100);
00649 #ifdef __TRACE__
00650 DEBUGMSG("certificate for %s\n", buf);
00651 #endif
00652 return (strcasecmp(buf, host) == 0);
00653 }
00654
00655 X509 *cp_client_get_server_certificate(cp_client *client)
00656 {
00657 return client->server_certificate;
00658 }
00659
00661 int cp_client_verify_hostname(cp_client *client)
00662 {
00663 return verify_host_name(client->server_certificate, client->host);
00664 }
00665 #endif
00666
00668 int cp_client_close(cp_client *client)
00669 {
00670 int rc = 0;
00671
00672 if (client)
00673 {
00674 #ifdef CP_USE_SSL
00675 if (client->use_ssl)
00676 {
00677 rc = SSL_shutdown(client->ssl);
00678 if (!rc)
00679 {
00680 shutdown(client->fd, SHUT_WR);
00681 rc = SSL_shutdown(client->ssl);
00682 }
00683 if (client->server_certificate)
00684 {
00685 X509_free(client->server_certificate);
00686 client->server_certificate = NULL;
00687 }
00688 }
00689 else
00690 #endif
00691 rc = shutdown(client->fd, SHUT_RDWR);
00692 if (rc == -1)
00693 cp_perror(CP_IO_ERROR, errno,
00694 "shutdown error on connection to %s",
00695 inet_ntoa(client->addr->sin_addr));
00696 rc = close(client->fd);
00697 if (rc == -1)
00698 cp_perror(CP_IO_ERROR, errno,
00699 "error closing connection to %s",
00700 inet_ntoa(client->addr->sin_addr));
00701 }
00702
00703 return rc;
00704 }
00705
00707 void cp_client_destroy(cp_client *client)
00708 {
00709 if (client)
00710 {
00711 if (client->host) free(client->host);
00712 if (client->hostspec) delete_hostent(client->hostspec);
00713 if (client->addr) free(client->addr);
00714 #ifdef CP_USE_SSL
00715 if (client->use_ssl)
00716 SSL_free(client->ssl);
00717 #endif
00718 free(client);
00719 }
00720 }
00721
00722 int cp_client_read(cp_client *client, char *buf, int len)
00723 {
00724 int rc;
00725 #ifdef CP_USE_SSL
00726 if (client->use_ssl)
00727 rc = SSL_read(client->ssl, buf, len);
00728 else
00729 #endif
00730
00731 rc = recv(client->fd, buf, len, 0);
00732 if (rc > 0) client->bytes_read += rc;
00733
00734 #ifdef _TCP_DUMP
00735 if (rc > 0)
00736 {
00737 buf[rc] = '\0';
00738 fprintf(stderr, "--- TCP DUMP ---\r\n%s\r\n --- PMUD PCT --- \r\n",
00739 buf);
00740 }
00741 #endif
00742
00743 return rc;
00744 }
00745
00746 #define CHUNK 0x1000
00747
00748 int cp_client_read_string(cp_client *client, cp_string *str, int len)
00749 {
00750 int rc;
00751 char buf[CHUNK];
00752 int read_len;
00753 int total = 0;
00754
00755 while (len == 0 || total < len)
00756 {
00757 read_len = (len == 0 || (len - total) > CHUNK) ? CHUNK : len - total;
00758 #ifdef CP_USE_SSL
00759 if (client->use_ssl)
00760 rc = SSL_read(client->ssl, buf, read_len);
00761 else
00762 #endif
00763
00764 rc = recv(client->fd, buf, read_len, 0);
00765
00766 if (rc <= 0)
00767 break;
00768 else
00769 client->bytes_read += rc;
00770 cp_string_cat_bin(str, buf, rc);
00771 total += rc;
00772 }
00773
00774 return total;
00775 }
00776
00777
00778
00779 int cp_client_write(cp_client *client, char *buf, int len)
00780 {
00781 int rc;
00782 #ifdef CP_USE_SSL
00783 if (client->use_ssl)
00784 {
00785 rc = SSL_write(client->ssl, buf, len);
00786 if (rc <= 0)
00787 {
00788 int err = SSL_get_error(client->ssl, rc);
00789 const char *reason = ERR_reason_error_string(err);
00790 cp_error(CP_IO_ERROR, "write failed: %s", reason ? reason : ssl_err_inf(err));
00791 }
00792 }
00793 else
00794 #endif
00795 rc = send(client->fd, buf, len, 0);
00796
00797 if (rc > 0) client->bytes_sent += rc;
00798
00799 return rc;
00800 }
00801
00802 int cp_client_write_string(cp_client *client, cp_string *str)
00803 {
00804 int rc;
00805 int total = 0;
00806 char *pos = cp_string_tocstr(str);
00807 int remaining = cp_string_len(str);
00808
00809 while (total < cp_string_len(str))
00810 {
00811 #ifdef CP_USE_SSL
00812 if (client->use_ssl)
00813 rc = SSL_write(client->ssl, pos, remaining);
00814 else
00815 #endif
00816 rc = send(client->fd, pos, remaining, 0);
00817
00818 if (rc <= 0)
00819 break;
00820 else
00821 client->bytes_sent += rc;
00822
00823 total += rc;
00824 remaining -= rc;
00825 pos = &pos[rc];
00826 }
00827
00828 return total;
00829 }