?? stdsoap2.c
字號:
/******************************************************************************/static inttcp_connect(struct soap *soap, const char *endpoint, const char *hostname, int port){ struct sockaddr_in sockaddr; int len = SOAP_BUFLEN; int set = 1; if (tcp_init(soap)) { soap_set_error(soap, "SOAP-ENV:Client", tcp_error(soap), "TCP initialization failed in tcp_connect()", SOAP_TCP_ERROR); return -1; } if (soap->socket >= 0) closesocket(soap->socket); soap->errmode = 0; if ((soap->socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) { soap->errnum = soap_errno; soap_set_error(soap, "SOAP-ENV:Client", tcp_error(soap), "TCP socket failed in tcp_connect()", SOAP_TCP_ERROR); return -1; } if (soap->keep_alive && setsockopt(soap->socket, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int))) { soap->errnum = soap_errno; soap_set_error(soap, "SOAP-ENV:Client", tcp_error(soap), "TCP setsockopt SO_KEEPALIVE failed in tcp_connect()", SOAP_TCP_ERROR); return -1; }#ifndef UNDER_CE if (setsockopt(soap->socket, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int))) { soap->errnum = soap_errno; soap_set_error(soap, "SOAP-ENV:Client", tcp_error(soap), "TCP setsockopt SO_SNDBUF failed in tcp_connect()", SOAP_TCP_ERROR); return -1; } if (setsockopt(soap->socket, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int))) { soap->errnum = soap_errno; soap_set_error(soap, "SOAP-ENV:Client", tcp_error(soap), "TCP setsockopt SO_RCVBUF failed in tcp_connect()", SOAP_TCP_ERROR); return -1; }#endif#ifdef TCP_NODELAY if (setsockopt(soap->socket, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int))) { soap->errnum = soap_errno; soap_set_error(soap, "SOAP-ENV:Client", tcp_error(soap), "TCP setsockopt TCP_NODELAY failed in tcp_connect()", SOAP_TCP_ERROR); return -1; }#endif memset(&sockaddr, 0, sizeof(sockaddr)); sockaddr.sin_family = AF_INET; DBGLOG(TEST,SOAP_MESSAGE(fdebug,"\nOpen socket: %d to hostname '%s'", soap->socket, hostname)); soap->errmode = 2; if (soap->proxy_host) { if (soap_gethost(soap, soap->proxy_host, &sockaddr.sin_addr)) { soap_set_error(soap, "SOAP-ENV:Client", tcp_error(soap), "TCP get proxy host by name failed in tcp_connect()", SOAP_TCP_ERROR); return -1; } sockaddr.sin_port = htons((short)soap->proxy_port); } else { if (soap_gethost(soap, hostname, &sockaddr.sin_addr)) { soap_set_error(soap, "SOAP-ENV:Client", tcp_error(soap), "TCP get host by name failed in tcp_connect()", SOAP_TCP_ERROR); return -1; } sockaddr.sin_port = htons((short)port); } soap->errmode = 0; if (soap->connect_timeout)#ifdef WIN32 { u_long nonblocking = 1; ioctlsocket(soap->socket, FIONBIO, &nonblocking); }#else fcntl(soap->socket, F_SETFL, fcntl(soap->socket, F_GETFL)|O_NONBLOCK);#endif for (;;) { if (connect(soap->socket, (struct sockaddr*)&sockaddr, sizeof(sockaddr))) { if (soap_errno == SOAP_EINPROGRESS && soap->connect_timeout) { struct timeval timeout; fd_set fd; if (soap->connect_timeout > 0) { timeout.tv_sec = soap->connect_timeout; timeout.tv_usec = 0; } else { timeout.tv_sec = -soap->connect_timeout/1000000; timeout.tv_usec = -soap->connect_timeout%1000000; } FD_ZERO(&fd); FD_SET(soap->socket, &fd); for (;;) { if (select(soap->socket + 1, NULL, &fd, NULL, &timeout) > 0) break; if (soap_errno != SOAP_EINTR) { soap->errnum = soap_errno; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\nCould not connect to host")); soap_closesock(soap); soap_set_error(soap, "SOAP-ENV:Client", "Timeout", "TCP connect failed in tcp_connect()", SOAP_TCP_ERROR); return -1; } } break; } else if (soap_errno != SOAP_EINTR) { soap->errnum = soap_errno; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\nCould not connect to host")); soap_closesock(soap); soap_set_error(soap, "SOAP-ENV:Client", tcp_error(soap), "TCP connect failed in tcp_connect()", SOAP_TCP_ERROR); return -1; } } else break; } if (soap->connect_timeout)#ifdef WIN32 { u_long blocking = 0; ioctlsocket(soap->socket, FIONBIO, &blocking); }#else fcntl(soap->socket, F_SETFL, fcntl(soap->socket, F_GETFL)&~O_NONBLOCK);#endif#ifdef WITH_OPENSSL if (!strncmp(endpoint, "https:", 6)) { int r; if (ssl_auth_init(soap)) { soap_set_error(soap, "SOAP-ENV:Client", "", "SSL initialization failed in tcp_connect()", SOAP_SSL_ERROR); return -1; } soap->ssl = SSL_new(soap_ssl_ctx); if (!soap->ssl) { soap->error = SOAP_SSL_ERROR; return -1; } soap->bio = BIO_new_socket(soap->socket, BIO_NOCLOSE); SSL_set_bio(soap->ssl, soap->bio, soap->bio); if ((r = SSL_connect(soap->ssl)) <= 0) { soap_set_error(soap, "SOAP-ENV:Client", ssl_error(soap, r), "SSL connect failed in tcp_connect()", SOAP_SSL_ERROR); return -1; } if (soap->require_server_auth) { X509 *peer; if (SSL_get_verify_result(soap->ssl) != X509_V_OK) { soap_set_error(soap, "SOAP-ENV:Client", "", "SSL certificate cannot be verified in tcp_connect()", SOAP_SSL_ERROR); return -1; } peer = SSL_get_peer_certificate(soap->ssl); X509_NAME_get_text_by_NID(X509_get_subject_name(peer), NID_commonName, soap->msgbuf, 1024); if (strcasecmp(soap->msgbuf, hostname)) { soap_set_error(soap, "SOAP-ENV:Client", "", "SSL certificate host name mismatch in tcp_connect()", SOAP_SSL_ERROR); return -1; } } }#endif soap->buffering = 1; return soap->socket;}/******************************************************************************/SOAP_FMAC1intSOAP_FMAC2soap_bind(struct soap *soap, const char *hostname, int port, int backlog){ struct sockaddr_in sockaddr; int len = SOAP_BUFLEN; int set = 1; soap->master = -1; soap->socket = -1; soap->errmode = 1; if (tcp_init(soap)) { soap_set_error(soap, "SOAP-ENV:Server", tcp_error(soap), "TCP init failed in soap_bind()", SOAP_TCP_ERROR); return -1; } soap->errmode = 0; if ((soap->master = socket(AF_INET, SOCK_STREAM, 0)) < 0) { soap->errnum = soap_errno; soap_set_error(soap, "SOAP-ENV:Server", tcp_error(soap), "TCP socket failed in soap_bind()", SOAP_TCP_ERROR); return -1; } if (setsockopt(soap->master, SOL_SOCKET, SO_REUSEADDR, (char*)&set, sizeof(int))) { soap->errnum = soap_errno; soap_set_error(soap, "SOAP-ENV:Client", tcp_error(soap), "TCP setsockopt SO_REUSEADDR failed in soap_bind()", SOAP_TCP_ERROR); return -1; } if (soap->keep_alive && setsockopt(soap->master, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int))) { soap->errnum = soap_errno; soap_set_error(soap, "SOAP-ENV:Client", tcp_error(soap), "TCP setsockopt SO_KEEPALIVE failed in soap_bind()", SOAP_TCP_ERROR); return -1; }#ifndef UNDER_CE if (setsockopt(soap->master, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int))) { soap->errnum = soap_errno; soap_set_error(soap, "SOAP-ENV:Client", tcp_error(soap), "TCP setsockopt SO_SNDBUF failed in soap_bind()", SOAP_TCP_ERROR); return -1; } if (setsockopt(soap->master, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int))) { soap->errnum = soap_errno; soap_set_error(soap, "SOAP-ENV:Client", tcp_error(soap), "TCP setsockopt SO_RCVBUF failed in soap_bind()", SOAP_TCP_ERROR); return -1; }#endif#ifdef TCP_NODELAY if (setsockopt(soap->master, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int))) { soap->errnum = soap_errno; soap_set_error(soap, "SOAP-ENV:Client", tcp_error(soap), "TCP setsockopt TCP_NODELAY failed in soap_bind()", SOAP_TCP_ERROR); return -1; }#endif memset(&sockaddr, 0, sizeof(sockaddr)); sockaddr.sin_family = AF_INET; soap->errmode = 2; if (hostname) { if (soap_gethost(soap, hostname, &sockaddr.sin_addr)) { soap_set_error(soap, "SOAP-ENV:Server", tcp_error(soap), "TCP get host by name failed in soap_bind()", SOAP_TCP_ERROR); return -1; } } else sockaddr.sin_addr.s_addr = htonl(INADDR_ANY); sockaddr.sin_port = htons((short)port); soap->errmode = 0; if (bind(soap->master, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) || listen(soap->master, backlog)) { soap->errnum = soap_errno; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\nCould not bind to host")); soap_closesock(soap); soap_set_error(soap, "SOAP-ENV:Server", tcp_error(soap), "TCP bind failed in soap_bind()", SOAP_TCP_ERROR); return -1; } return soap->master;}/******************************************************************************/SOAP_FMAC1intSOAP_FMAC2soap_accept(struct soap *soap){ struct sockaddr_in sockaddr; int len = SOAP_BUFLEN; int set = 1;#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) socklen_t n = sizeof(struct sockaddr_in);#else int n = sizeof(struct sockaddr_in);#endif memset(&sockaddr, 0, sizeof(sockaddr)); soap->socket = -1; soap->errmode = 0; if (soap->master > 0) { for (;;) { if (soap->accept_timeout) { struct timeval timeout; fd_set fd; if (soap->accept_timeout > 0) { timeout.tv_sec = soap->accept_timeout; timeout.tv_usec = 0; } else { timeout.tv_sec = -soap->accept_timeout/1000000; timeout.tv_usec = -soap->accept_timeout%1000000; } FD_ZERO(&fd); FD_SET(soap->master, &fd); for (;;) { if (select(soap->master + 1, &fd, &fd, NULL, &timeout) > 0) break; if (soap_errno != SOAP_EINTR) { soap->errnum = soap_errno; soap_set_error(soap, "SOAP-ENV:Server", "Timeout", "TCP accept failed in soap_accept()", SOAP_TCP_ERROR); return -1; } }#ifdef WIN32 { u_long nonblocking = 1; ioctlsocket(soap->master, FIONBIO, &nonblocking); }#else fcntl(soap->master, F_SETFL, fcntl(soap->master, F_GETFL)|O_NONBLOCK);#endif } if ((soap->socket = accept(soap->master, (struct sockaddr*)&sockaddr, &n)) >= 0) { soap->ip = ntohl(sockaddr.sin_addr.s_addr); if (soap->keep_alive && setsockopt(soap->socket, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int))) { soap->errnum = soap_errno; soap_set_error(soap, "SOAP-ENV:Server", tcp_error(soap), "TCP setsockopt SO_KEEPALIVE failed in soap_accept()", SOAP_TCP_ERROR); return -1; }#ifndef UNDER_CE if (setsockopt(soap->socket, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int))) { soap->errnum = soap_errno; soap_set_error(soap, "SOAP-ENV:Server", tcp_error(soap), "TCP setsockopt SO_SNDBUF failed in soap_accept()", SOAP_TCP_ERROR); return -1; } if (setsockopt(soap->socket, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int))) { soap->errnum = soap_errno; soap_set_error(soap, "SOAP-ENV:Server", tcp_error(soap), "TCP setsockopt SO_RCVBUF failed in soap_accept()", SOAP_TCP_ERROR); return -1; }#endif#ifdef TCP_NODELAY if (setsockopt(soap->socket, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int))) { soap->errnum = soap_errno; soap_set_error(soap, "SOAP-ENV:Server", tcp_error(soap), "TCP setsockopt TCP_NODELAY failed in soap_accept()", SOAP_TCP_ERROR); return -1; }#endif return soap->socket; } else if (soap_errno != SOAP_EINTR && soap_errno != SOAP_EWOULDBLOCK) { soap->errnum = soap_errno; soap_set_error(soap, "SOAP-ENV:Server", tcp_error(soap), "TCP accept failed in soap_accept()", SOAP_TCP_ERROR); return -1; } } } else { soap_set_error(soap, "SOAP-ENV:Server", "", "TCP no master socket in soap_accept()", SOAP_TCP_ERROR); return -1; }}/******************************************************************************/static inttcp_disconnect(struct soap *soap){#ifdef WITH_OPENSSL if (soap->ssl) { int r = SSL_shutdown(soap->ssl); if (!r) { if (soap->socket >= 0) shutdown(soap->socket, 1); r = SSL_shutdown(soap->ssl); } DBGLOG(TEST, if (r != 1) SOAP_MESSAGE(fdebug, "\nShutdown failed: %d", SSL_get_error(soap->ssl, r))); SSL_free(soap->ssl); soap->ssl = NULL; if (r != 1) return SOAP_SSL_ERROR; }#endif if (soap->socket >= 0) { DBGLOG(TEST,SOAP_MESSAGE(fdebug,"\nClosing socket %d", soap->socket)); closesocket(soap->socket); soap->socket = -1; } return SOAP_OK;}/******************************************************************************/SOAP_FMAC1intSOAP_FMAC2soap_closesock(struct soap *soap){ if (!soap->keep_alive) return soap->error = soap->fclose(soap); return SOAP_OK;}/******************************************************************************/inthash_id(const char *s){ register int h = 0; while (*s) h += *s++&0x1F; return h%SOAP_IDHASH;}/******************************************************************************/SOAP_FMAC1voidSOAP_FMAC2soap_init_pht(struct soap *soap){ int i; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\nInitializing pointer hashtable")); for (i = 0; i < SOAP_PTRHASH; i++) soap->pht[i] = NULL;}/******************************************************************************/SOAP_FMAC1struct soap*SOAP_FMAC2soap_new(){ struct soap *soap = (struct soap*)malloc(sizeof(struct soap)); if (soap) soap_init(soap); return soap;}/******************************************************************************/SOAP_FMAC1voidSOAP_FMAC2soap_free_pht(struct soap *soap){ struct soap_plist *pp, *next; int i; for (i = 0; i < SOAP_PTRHASH; i++) { for (pp = soap->pht[i]; pp; pp = next) { next = pp->next; free(pp); } soap->pht[i] = NULL; }}/******************************************************************************/SOAP_FMAC1intSOAP_FMAC2soap_pointer_lookup(struct soap *soap, const void *p, int type, struct soap_plist **ppp){ struct soap_plist *pp; *ppp = NULL; if (!p) return 0; for (pp = soap->pht[hash_ptr(p)]; pp; pp = pp->next) if (pp->ptr == p && pp->type == type) { *ppp = pp; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\nLookup location=%p type=%d id=%d", p, type, pp->id)); return pp->id; } DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\nLookup location=%p type=%d: not found", p, type)); return 0;}/******************************************************************************/SOAP_FMAC1intSOAP_FMAC2soap_array_pointer_lookup(struct soap *soap, const void *p, int n, int type, struct soap_plist **ppp){ struct soap_plist *pp; *ppp = NULL; if (!p || !*(void**)p) return 0; type |= 1024; for (pp = soap->pht[hash_ptr(*(void**)p)]; pp; pp = pp->next) if (pp->type == type && *(void**)pp->ptr == *(void**)p && *((int*)pp->ptr+1) == n) { *ppp = pp; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\nArray lookup location=%p type=%d id=%d", p, type, pp->id)); return pp->id; } DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\nArray lookup location=%p type=%d: not found", p, type)); return 0;}/******************************************************************************/SOAP_FMAC1intSOAP_FMAC2soap_pointer_enter(struct soap *soap, const void *p, int type, struct soap_plist **ppp){ int h; struct soap_plist *pp; if (!p) { *ppp = NULL; return 0;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -