diff options
Diffstat (limited to 'util/src/network_handler.c')
-rw-r--r-- | util/src/network_handler.c | 1292 |
1 files changed, 646 insertions, 646 deletions
diff --git a/util/src/network_handler.c b/util/src/network_handler.c index ae41943..40c9723 100644 --- a/util/src/network_handler.c +++ b/util/src/network_handler.c @@ -1,646 +1,646 @@ -/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <axutil_network_handler.h>
-#include <fcntl.h>
-
-
-#if defined(WIN32)
-/* fix for an older version of winsock2.h */
-#if !defined(SO_EXCLUSIVEADDRUSE)
-#define SO_EXCLUSIVEADDRUSE ((int)(~SO_REUSEADDR))
-#endif
-#endif
-
-#if defined(WIN32)
-static int is_init_socket = 0;
-axis2_bool_t axis2_init_socket(
-);
-#endif
-
-AXIS2_EXTERN axis2_socket_t AXIS2_CALL
-axutil_network_handler_open_socket(
- const axutil_env_t *env,
- char *server,
- int port)
-{
- axis2_socket_t sock = AXIS2_INVALID_SOCKET;
- struct sockaddr_in sock_addr;
- struct linger ll;
- int nodelay = 1;
-
-#if defined(WIN32)
- if (is_init_socket == 0)
- {
- axis2_init_socket();
- is_init_socket = 1;
- }
-#endif
-
- AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
- AXIS2_PARAM_CHECK(env->error, server, AXIS2_INVALID_SOCKET);
-
-#ifndef WIN32
- if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
- /*AF_INET is not defined in sys/socket.h but PF_INET */
- {
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
- return AXIS2_INVALID_SOCKET;
- }
-#else
- if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
- /* In Win 32 if the socket creation failed it return 0 not a negative value */
- {
- char buf[AXUTIL_WIN32_ERROR_BUFSIZE];
- /* Get the detailed error message */
- axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE);
- AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf);
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
- return AXIS2_INVALID_SOCKET;
- }
-#endif
-
- memset(&sock_addr, 0, sizeof(sock_addr));
- sock_addr.sin_family = AF_INET;
- sock_addr.sin_addr.s_addr = inet_addr(server); /*arpa/inet.d */
-
- if(sock_addr.sin_addr.s_addr == AXIS2_INADDR_NONE) /*netinet/in.h */
- {
- /*
- * server may be a host name
- */
- struct hostent *lphost = NULL;
- lphost = gethostbyname(server);
-
- if(lphost)
- {
- sock_addr.sin_addr.s_addr = ((struct in_addr *)lphost->h_addr)->s_addr;
- }
- else
- {
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_ADDRESS, AXIS2_FAILURE);
- return AXIS2_INVALID_SOCKET;
- }
- }
-
- sock_addr.sin_port = htons((axis2_unsigned_short_t)port);
-
- /* Connect to server */
- if(connect(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) < 0)
- {
- AXIS2_CLOSE_SOCKET(sock);
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
- return AXIS2_INVALID_SOCKET;
- }
- setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (const char *)&nodelay, sizeof(nodelay));
- ll.l_onoff = 1;
- ll.l_linger = 5;
- setsockopt(sock, SOL_SOCKET, SO_LINGER, (const char *)&ll, sizeof(struct linger));
- return sock;
-}
-
-AXIS2_EXTERN axis2_socket_t AXIS2_CALL
-axutil_network_handler_create_server_socket(
- const axutil_env_t *env,
- int port)
-{
- axis2_socket_t sock = AXIS2_INVALID_SOCKET;
- axis2_socket_t i = 0;
- struct sockaddr_in sock_addr;
-
- AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
-#if defined(WIN32)
- if (is_init_socket == 0)
- {
- axis2_init_socket();
- is_init_socket = 1;
- }
-#endif
- sock = socket(AF_INET, SOCK_STREAM, 0);
-
-#ifndef WIN32
- if(sock < 0)
- {
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
- return AXIS2_INVALID_SOCKET;
- }
-#else
- if (sock == INVALID_SOCKET)
- {
- axis2_char_t buf[AXUTIL_WIN32_ERROR_BUFSIZE];
- axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE);
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
- AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf);
- return AXIS2_INVALID_SOCKET;
- }
-#endif
- /* Address re-use */
- i = 1;
-#if defined(WIN32)
- setsockopt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *) &i, sizeof(axis2_socket_t)); /*casted 4th param to char* */
-#else
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&i, sizeof(axis2_socket_t)); /*casted 4th param to char* */
-#endif
-
- /* Exec behaviour */
- AXIS2_CLOSE_SOCKET_ON_EXIT(sock);
- memset(&sock_addr, 0, sizeof(sock_addr));
-
- sock_addr.sin_family = AF_INET;
- sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);
- sock_addr.sin_port = htons((axis2_unsigned_short_t)port);
-
- /* Bind the socket to our port number */
- if(bind(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) < 0)
- {
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_BIND_FAILED, AXIS2_FAILURE);
- return AXIS2_INVALID_SOCKET;
- }
- if(listen(sock, 50) < 0)
- {
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_LISTEN_FAILED, AXIS2_FAILURE);
- return AXIS2_INVALID_SOCKET;
- }
- return sock;
-}
-
-AXIS2_EXTERN axis2_status_t AXIS2_CALL
-axutil_network_handler_close_socket(
- const axutil_env_t *env,
- axis2_socket_t socket)
-{
- int i = 0;
- char buf[32];
- if(socket < 0)
- {
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_SOCKET, AXIS2_FAILURE);
- return AXIS2_FAILURE;
- }
- shutdown(socket, AXIS2_SHUT_WR);
- axutil_network_handler_set_sock_option(env, socket, SO_RCVTIMEO, 1);
- i = recv(socket, buf, 32, 0);
- AXIS2_CLOSE_SOCKET(socket);
- return AXIS2_SUCCESS;
-}
-
-AXIS2_EXTERN axis2_status_t AXIS2_CALL
-axutil_network_handler_set_sock_option(
- const axutil_env_t *env,
- axis2_socket_t socket,
- int option,
- int value)
-{
- if(option == SO_RCVTIMEO || option == SO_SNDTIMEO)
- {
-#if defined(WIN32)
- DWORD tv = value; /* windows expects milliseconds in a DWORD */
-#else
- struct timeval tv;
- /* we deal with milliseconds */
- tv.tv_sec = value / 1000;
- tv.tv_usec = (value % 1000) * 1000;
-#endif
- setsockopt(socket, SOL_SOCKET, option, (char *)&tv, sizeof(tv));
- return AXIS2_SUCCESS;
- }
- else if(option == SO_REUSEADDR)
- {
- if((setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (char *)&value, sizeof(value))) < 0)
- {
- return AXIS2_FAILURE;
- }
- return AXIS2_SUCCESS;
- }
- return AXIS2_FAILURE;
-}
-
-AXIS2_EXTERN axis2_socket_t AXIS2_CALL
-axutil_network_handler_svr_socket_accept(
- const axutil_env_t *env,
- axis2_socket_t svr_socket)
-{
- struct sockaddr cli_addr;
- struct linger ll;
- int nodelay = 1;
- axis2_socket_len_t cli_len = 0;
- axis2_socket_t cli_socket = AXIS2_INVALID_SOCKET;
- AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
-
- cli_len = sizeof(cli_addr);
- cli_socket = accept(svr_socket, (struct sockaddr *)&cli_addr, &cli_len);
-#ifndef WIN32
- if(cli_socket < 0)
- {
- AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
- "[Axis2][network_handler] Socket accept \
- failed");
- }
-#else
- if (cli_socket == INVALID_SOCKET)
- {
- axis2_char_t buf[AXUTIL_WIN32_ERROR_BUFSIZE];
- axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE);
- AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf);
- }
-#endif
-
- setsockopt(svr_socket, IPPROTO_TCP, TCP_NODELAY, (const char *)&nodelay, (int)sizeof(nodelay));
- /* We are sure that the difference lies within the int range */
- ll.l_onoff = 1;
- ll.l_linger = 5;
- setsockopt(cli_socket, SOL_SOCKET, SO_LINGER, (const char *)&ll, (int)sizeof(struct linger));
- /* We are sure that the difference lies within the int range */
- return cli_socket;
-}
-
-#if defined (WIN32)
-axis2_bool_t
-axis2_init_socket(
-)
-{
- WORD wVersionRequested;
- WSADATA wsaData;
- int err;
- wVersionRequested = MAKEWORD(2, 2);
-
- err = WSAStartup(wVersionRequested, &wsaData);
-
- if (err != 0)
- return 0; /* WinSock 2.2 not found */
-
- /* Confirm that the WinSock DLL supports 2.2.
- * Note that if the DLL supports versions greater
- * than 2.2 in addition to 2.2, it will still return
- * 2.2 in wVersion since that is the version we
- * requested.
- */
-
- if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
- {
- WSACleanup();
- return 0; /* WinSock 2.2 not supported */
- }
- return 1;
-}
-#endif
-
-AXIS2_EXTERN axis2_char_t *AXIS2_CALL
-axutil_network_handler_get_svr_ip(
- const axutil_env_t *env,
- axis2_socket_t socket)
-{
- struct sockaddr_in addr;
- axis2_socket_len_t len = sizeof(addr);
- char *ret = NULL;
- memset(&addr, 0, sizeof(addr));
- if(getsockname(socket, (struct sockaddr *)&addr, &len) < 0)
- {
- return NULL;
- }
- ret = inet_ntoa(addr.sin_addr);
- return ret;
-}
-
-AXIS2_EXTERN axis2_char_t *AXIS2_CALL
-axutil_network_handler_get_peer_ip(
- const axutil_env_t *env,
- axis2_socket_t socket)
-{
- struct sockaddr_in addr;
- axis2_socket_len_t len = sizeof(addr);
- char *ret = NULL;
- memset(&addr, 0, sizeof(addr));
- if(getpeername(socket, (struct sockaddr *)&addr, &len) < 0)
- {
- return NULL;
- }
- ret = inet_ntoa(addr.sin_addr);
- return ret;
-}
-
-AXIS2_EXTERN axis2_socket_t AXIS2_CALL
-axutil_network_handler_create_dgram_svr_socket(
- const axutil_env_t *env,
- int port)
-{
- axis2_socket_t sock = AXIS2_INVALID_SOCKET;
- struct sockaddr_in sock_addr;
-
- AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
-#if defined(WIN32)
- if (is_init_socket == 0)
- {
- axis2_init_socket();
- is_init_socket = 1;
- }
-#endif
- sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-
-#ifndef WIN32
- if(sock < 0)
- {
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
- return AXIS2_INVALID_SOCKET;
- }
-#else
- if (sock == INVALID_SOCKET)
- {
- axis2_char_t buf[AXUTIL_WIN32_ERROR_BUFSIZE];
- axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE);
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
- AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf);
- return AXIS2_INVALID_SOCKET;
- }
-#endif
- /* Exec behaviour */
- AXIS2_CLOSE_SOCKET_ON_EXIT(sock);
- memset(&sock_addr, 0, sizeof(sock_addr));
-
- sock_addr.sin_family = AF_INET;
- sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);
- sock_addr.sin_port = htons((axis2_unsigned_short_t)port);
-
- /* Bind the socket to our port number */
- if(bind(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) < 0)
- {
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_BIND_FAILED, AXIS2_FAILURE);
- return AXIS2_INVALID_SOCKET;
- }
- return sock;
-}
-
-AXIS2_EXTERN axis2_socket_t AXIS2_CALL
-axutil_network_handler_open_dgram_socket(
- const axutil_env_t *env)
-{
- axis2_socket_t sock = AXIS2_INVALID_SOCKET;
-#if defined(WIN32)
- if (is_init_socket == 0)
- {
- axis2_init_socket();
- is_init_socket = 1;
- }
-#endif
-
-#ifndef WIN32
- if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
- /*AF_INET is not defined in sys/socket.h but PF_INET */
- {
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
- return AXIS2_INVALID_SOCKET;
- }
-#else
- if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)
- /* In Win 32 if the socket creation failed it return 0 not a negative value */
- {
- char buf[AXUTIL_WIN32_ERROR_BUFSIZE];
- /* Get the detailed error message */
- axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE);
- AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf);
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
- return AXIS2_INVALID_SOCKET;
- }
-#endif
- return sock;
-}
-
-/*
- * This function blocks until data is available to read from the socket
- * and read all the data in the socket. If the buffer size specified is
- * lesser than the actual data a failure will be returned.
- */
-AXIS2_EXTERN axis2_status_t AXIS2_CALL
-axutil_network_handler_read_dgram(
- const axutil_env_t *env,
- axis2_socket_t sock,
- axis2_char_t *buffer,
- int *buf_len,
- axis2_char_t **addr,
- int *port)
-{
- struct sockaddr_in sender_address;
- int received = 0;
- socklen_t sender_address_size;
-
- sender_address_size = sizeof(sender_address);
- received = recvfrom(sock, buffer, *buf_len, 0, (struct sockaddr *)&sender_address, &sender_address_size);
-#ifdef WIN32
- if (SOCKET_ERROR == received)
- {
- axis2_char_t buf[AXUTIL_WIN32_ERROR_BUFSIZE];
- axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE);
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
- AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf);
- return AXIS2_FAILURE;
- }
-#else
- if(received < 0)
- {
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
- return AXIS2_INVALID_SOCKET;
- }
-#endif
- if(port && addr)
- {
- *port = ntohs(sender_address.sin_port);
- *addr = inet_ntoa(sender_address.sin_addr);
- }
- *buf_len = received;
- return AXIS2_SUCCESS;
-}
-
-/*
- * Sends a datagram to the specified location.
- */
-AXIS2_EXTERN axis2_status_t AXIS2_CALL
-axutil_network_handler_send_dgram(
- const axutil_env_t *env,
- axis2_socket_t sock,
- axis2_char_t *buff,
- int *buf_len,
- axis2_char_t *addr,
- int dest_port,
- int *source_port)
-{
- struct sockaddr_in recv_addr, source_addr;
- int send_bytes = 0;
- unsigned int recv_addr_size = 0;
- socklen_t source_addr_size = sizeof(source_addr);
- recv_addr_size = sizeof(recv_addr);
-
- memset(&recv_addr, 0, sizeof(recv_addr));
- memset(&recv_addr, 0, sizeof(source_addr));
-
- recv_addr.sin_addr.s_addr = inet_addr(addr);
- if(recv_addr.sin_addr.s_addr == AXIS2_INADDR_NONE) /*netinet/in.h */
- {
- /*
- * server may be a host name
- */
- struct hostent *lphost = NULL;
- lphost = gethostbyname(addr);
-
- if(lphost)
- {
- recv_addr.sin_addr.s_addr = ((struct in_addr *)lphost->h_addr)->s_addr;
- }
- else
- {
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_ADDRESS, AXIS2_FAILURE);
- return AXIS2_FAILURE;
- }
- }
-
- recv_addr.sin_family = AF_INET;
- recv_addr.sin_port = htons((axis2_unsigned_short_t)dest_port);
-
- send_bytes = sendto(sock, buff, *buf_len, 0, (struct sockaddr *)&recv_addr, recv_addr_size);
-
- getsockname(sock, (struct sockaddr *)&source_addr, &source_addr_size);
-
-#ifdef WIN32
- if (send_bytes == SOCKET_ERROR)
- {
- axis2_char_t buf[AXUTIL_WIN32_ERROR_BUFSIZE];
- axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE);
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
- AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf);
- return AXIS2_FAILURE;
- }
-#else
- if(send_bytes < 0)
- {
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
- return AXIS2_FAILURE;
- }
-#endif
- if(source_port)
- {
- *source_port = ntohs(source_addr.sin_port);
- }
- *buf_len = send_bytes;
- return AXIS2_SUCCESS;
-}
-
-AXIS2_EXTERN axis2_status_t AXIS2_CALL
-axutil_network_handler_bind_socket(
- const axutil_env_t *env,
- axis2_socket_t sock,
- int port)
-{
- struct sockaddr_in source_addr;
-
- memset(&source_addr, 0, sizeof(source_addr));
- source_addr.sin_family = AF_INET;
- source_addr.sin_addr.s_addr = htonl(INADDR_ANY);
- source_addr.sin_port = htons((axis2_unsigned_short_t)port);
-#ifdef WIN32
- if (bind(sock, (struct sockaddr *)&source_addr, sizeof(source_addr)) == SOCKET_ERROR)
- {
- axis2_char_t buf[AXUTIL_WIN32_ERROR_BUFSIZE];
- axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE);
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
- AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf);
- return AXIS2_FAILURE;
- }
-#else
- if(bind(sock, (struct sockaddr *)&source_addr, sizeof(source_addr)) < 0)
- {
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
- return AXIS2_INVALID_SOCKET;
- }
-#endif
- return AXIS2_SUCCESS;
-}
-
-AXIS2_EXTERN axis2_socket_t AXIS2_CALL
-axutil_network_hadler_create_multicast_svr_socket(
- const axutil_env_t *env,
- int port,
- axis2_char_t *mul_addr)
-{
- axis2_socket_t sock = AXIS2_INVALID_SOCKET;
- struct sockaddr_in sock_addr;
- struct ip_mreq mc_req;
-
- AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
-#if defined(WIN32)
- if (is_init_socket == 0)
- {
- axis2_init_socket();
- is_init_socket = 1;
- }
-#endif
- sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-
-#ifndef WIN32
- if(sock < 0)
- {
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
- return AXIS2_FAILURE;
- }
-#else
- if (sock == INVALID_SOCKET)
- {
- axis2_char_t buf[AXUTIL_WIN32_ERROR_BUFSIZE];
- axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE);
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
- AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf);
- return AXIS2_FAILURE;
- }
-#endif
-
- /* Exec behaviour */
- AXIS2_CLOSE_SOCKET_ON_EXIT(sock);
- memset(&sock_addr, 0, sizeof(sock_addr));
-
- sock_addr.sin_family = AF_INET;
- sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);
- sock_addr.sin_port = htons((axis2_unsigned_short_t)port);
-
- /* Bind the socket to our port number */
- if(bind(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) < 0)
- {
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_BIND_FAILED, AXIS2_FAILURE);
- return AXIS2_INVALID_SOCKET;
- }
-
- /* Send an IGMP request to join the multicast group */
- mc_req.imr_multiaddr.s_addr = inet_addr(mul_addr);
- mc_req.imr_interface.s_addr = htonl(INADDR_ANY);
-#ifdef WIN32
- if ((setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &mc_req, sizeof(mc_req))) == SOCKET_ERROR)
- {
- axis2_char_t buf[AXUTIL_WIN32_ERROR_BUFSIZE];
- axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE);
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
- AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf);
- return AXIS2_FAILURE;
- }
-#else
- if((setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mc_req, sizeof(mc_req))) < 0)
- {
- AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
- return AXIS2_FAILURE;
- }
-#endif
- return sock;
-}
-
+/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <axutil_network_handler.h> +#include <fcntl.h> + + +#if defined(WIN32) +/* fix for an older version of winsock2.h */ +#if !defined(SO_EXCLUSIVEADDRUSE) +#define SO_EXCLUSIVEADDRUSE ((int)(~SO_REUSEADDR)) +#endif +#endif + +#if defined(WIN32) +static int is_init_socket = 0; +axis2_bool_t axis2_init_socket( +); +#endif + +AXIS2_EXTERN axis2_socket_t AXIS2_CALL +axutil_network_handler_open_socket( + const axutil_env_t *env, + char *server, + int port) +{ + axis2_socket_t sock = AXIS2_INVALID_SOCKET; + struct sockaddr_in sock_addr; + struct linger ll; + int nodelay = 1; + +#if defined(WIN32) + if (is_init_socket == 0) + { + axis2_init_socket(); + is_init_socket = 1; + } +#endif + + AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE); + AXIS2_PARAM_CHECK(env->error, server, AXIS2_INVALID_SOCKET); + +#ifndef WIN32 + if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) + /*AF_INET is not defined in sys/socket.h but PF_INET */ + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE); + return AXIS2_INVALID_SOCKET; + } +#else + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) + /* In Win 32 if the socket creation failed it return 0 not a negative value */ + { + char buf[AXUTIL_WIN32_ERROR_BUFSIZE]; + /* Get the detailed error message */ + axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE); + return AXIS2_INVALID_SOCKET; + } +#endif + + memset(&sock_addr, 0, sizeof(sock_addr)); + sock_addr.sin_family = AF_INET; + sock_addr.sin_addr.s_addr = inet_addr(server); /*arpa/inet.d */ + + if(sock_addr.sin_addr.s_addr == AXIS2_INADDR_NONE) /*netinet/in.h */ + { + /* + * server may be a host name + */ + struct hostent *lphost = NULL; + lphost = gethostbyname(server); + + if(lphost) + { + sock_addr.sin_addr.s_addr = ((struct in_addr *)lphost->h_addr)->s_addr; + } + else + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_ADDRESS, AXIS2_FAILURE); + return AXIS2_INVALID_SOCKET; + } + } + + sock_addr.sin_port = htons((axis2_unsigned_short_t)port); + + /* Connect to server */ + if(connect(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) < 0) + { + AXIS2_CLOSE_SOCKET(sock); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE); + return AXIS2_INVALID_SOCKET; + } + setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (const char *)&nodelay, sizeof(nodelay)); + ll.l_onoff = 1; + ll.l_linger = 5; + setsockopt(sock, SOL_SOCKET, SO_LINGER, (const char *)&ll, sizeof(struct linger)); + return sock; +} + +AXIS2_EXTERN axis2_socket_t AXIS2_CALL +axutil_network_handler_create_server_socket( + const axutil_env_t *env, + int port) +{ + axis2_socket_t sock = AXIS2_INVALID_SOCKET; + axis2_socket_t i = 0; + struct sockaddr_in sock_addr; + + AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE); +#if defined(WIN32) + if (is_init_socket == 0) + { + axis2_init_socket(); + is_init_socket = 1; + } +#endif + sock = socket(AF_INET, SOCK_STREAM, 0); + +#ifndef WIN32 + if(sock < 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE); + return AXIS2_INVALID_SOCKET; + } +#else + if (sock == INVALID_SOCKET) + { + axis2_char_t buf[AXUTIL_WIN32_ERROR_BUFSIZE]; + axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf); + return AXIS2_INVALID_SOCKET; + } +#endif + /* Address re-use */ + i = 1; +#if defined(WIN32) + setsockopt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *) &i, sizeof(axis2_socket_t)); /*casted 4th param to char* */ +#else + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&i, sizeof(axis2_socket_t)); /*casted 4th param to char* */ +#endif + + /* Exec behaviour */ + AXIS2_CLOSE_SOCKET_ON_EXIT(sock); + memset(&sock_addr, 0, sizeof(sock_addr)); + + sock_addr.sin_family = AF_INET; + sock_addr.sin_addr.s_addr = htonl(INADDR_ANY); + sock_addr.sin_port = htons((axis2_unsigned_short_t)port); + + /* Bind the socket to our port number */ + if(bind(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) < 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_BIND_FAILED, AXIS2_FAILURE); + return AXIS2_INVALID_SOCKET; + } + if(listen(sock, 50) < 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_LISTEN_FAILED, AXIS2_FAILURE); + return AXIS2_INVALID_SOCKET; + } + return sock; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_network_handler_close_socket( + const axutil_env_t *env, + axis2_socket_t socket) +{ + int i = 0; + char buf[32]; + if(socket < 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_SOCKET, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + shutdown(socket, AXIS2_SHUT_WR); + axutil_network_handler_set_sock_option(env, socket, SO_RCVTIMEO, 1); + i = recv(socket, buf, 32, 0); + AXIS2_CLOSE_SOCKET(socket); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_network_handler_set_sock_option( + const axutil_env_t *env, + axis2_socket_t socket, + int option, + int value) +{ + if(option == SO_RCVTIMEO || option == SO_SNDTIMEO) + { +#if defined(WIN32) + DWORD tv = value; /* windows expects milliseconds in a DWORD */ +#else + struct timeval tv; + /* we deal with milliseconds */ + tv.tv_sec = value / 1000; + tv.tv_usec = (value % 1000) * 1000; +#endif + setsockopt(socket, SOL_SOCKET, option, (char *)&tv, sizeof(tv)); + return AXIS2_SUCCESS; + } + else if(option == SO_REUSEADDR) + { + if((setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (char *)&value, sizeof(value))) < 0) + { + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_socket_t AXIS2_CALL +axutil_network_handler_svr_socket_accept( + const axutil_env_t *env, + axis2_socket_t svr_socket) +{ + struct sockaddr cli_addr; + struct linger ll; + int nodelay = 1; + axis2_socket_len_t cli_len = 0; + axis2_socket_t cli_socket = AXIS2_INVALID_SOCKET; + AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE); + + cli_len = sizeof(cli_addr); + cli_socket = accept(svr_socket, (struct sockaddr *)&cli_addr, &cli_len); +#ifndef WIN32 + if(cli_socket < 0) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "[Axis2][network_handler] Socket accept \ + failed"); + } +#else + if (cli_socket == INVALID_SOCKET) + { + axis2_char_t buf[AXUTIL_WIN32_ERROR_BUFSIZE]; + axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf); + } +#endif + + setsockopt(svr_socket, IPPROTO_TCP, TCP_NODELAY, (const char *)&nodelay, (int)sizeof(nodelay)); + /* We are sure that the difference lies within the int range */ + ll.l_onoff = 1; + ll.l_linger = 5; + setsockopt(cli_socket, SOL_SOCKET, SO_LINGER, (const char *)&ll, (int)sizeof(struct linger)); + /* We are sure that the difference lies within the int range */ + return cli_socket; +} + +#if defined (WIN32) +axis2_bool_t +axis2_init_socket( +) +{ + WORD wVersionRequested; + WSADATA wsaData; + int err; + wVersionRequested = MAKEWORD(2, 2); + + err = WSAStartup(wVersionRequested, &wsaData); + + if (err != 0) + return 0; /* WinSock 2.2 not found */ + + /* Confirm that the WinSock DLL supports 2.2. + * Note that if the DLL supports versions greater + * than 2.2 in addition to 2.2, it will still return + * 2.2 in wVersion since that is the version we + * requested. + */ + + if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) + { + WSACleanup(); + return 0; /* WinSock 2.2 not supported */ + } + return 1; +} +#endif + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_network_handler_get_svr_ip( + const axutil_env_t *env, + axis2_socket_t socket) +{ + struct sockaddr_in addr; + axis2_socket_len_t len = sizeof(addr); + char *ret = NULL; + memset(&addr, 0, sizeof(addr)); + if(getsockname(socket, (struct sockaddr *)&addr, &len) < 0) + { + return NULL; + } + ret = inet_ntoa(addr.sin_addr); + return ret; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_network_handler_get_peer_ip( + const axutil_env_t *env, + axis2_socket_t socket) +{ + struct sockaddr_in addr; + axis2_socket_len_t len = sizeof(addr); + char *ret = NULL; + memset(&addr, 0, sizeof(addr)); + if(getpeername(socket, (struct sockaddr *)&addr, &len) < 0) + { + return NULL; + } + ret = inet_ntoa(addr.sin_addr); + return ret; +} + +AXIS2_EXTERN axis2_socket_t AXIS2_CALL +axutil_network_handler_create_dgram_svr_socket( + const axutil_env_t *env, + int port) +{ + axis2_socket_t sock = AXIS2_INVALID_SOCKET; + struct sockaddr_in sock_addr; + + AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE); +#if defined(WIN32) + if (is_init_socket == 0) + { + axis2_init_socket(); + is_init_socket = 1; + } +#endif + sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + +#ifndef WIN32 + if(sock < 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE); + return AXIS2_INVALID_SOCKET; + } +#else + if (sock == INVALID_SOCKET) + { + axis2_char_t buf[AXUTIL_WIN32_ERROR_BUFSIZE]; + axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf); + return AXIS2_INVALID_SOCKET; + } +#endif + /* Exec behaviour */ + AXIS2_CLOSE_SOCKET_ON_EXIT(sock); + memset(&sock_addr, 0, sizeof(sock_addr)); + + sock_addr.sin_family = AF_INET; + sock_addr.sin_addr.s_addr = htonl(INADDR_ANY); + sock_addr.sin_port = htons((axis2_unsigned_short_t)port); + + /* Bind the socket to our port number */ + if(bind(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) < 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_BIND_FAILED, AXIS2_FAILURE); + return AXIS2_INVALID_SOCKET; + } + return sock; +} + +AXIS2_EXTERN axis2_socket_t AXIS2_CALL +axutil_network_handler_open_dgram_socket( + const axutil_env_t *env) +{ + axis2_socket_t sock = AXIS2_INVALID_SOCKET; +#if defined(WIN32) + if (is_init_socket == 0) + { + axis2_init_socket(); + is_init_socket = 1; + } +#endif + +#ifndef WIN32 + if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + /*AF_INET is not defined in sys/socket.h but PF_INET */ + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE); + return AXIS2_INVALID_SOCKET; + } +#else + if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) + /* In Win 32 if the socket creation failed it return 0 not a negative value */ + { + char buf[AXUTIL_WIN32_ERROR_BUFSIZE]; + /* Get the detailed error message */ + axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE); + return AXIS2_INVALID_SOCKET; + } +#endif + return sock; +} + +/* + * This function blocks until data is available to read from the socket + * and read all the data in the socket. If the buffer size specified is + * lesser than the actual data a failure will be returned. + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_network_handler_read_dgram( + const axutil_env_t *env, + axis2_socket_t sock, + axis2_char_t *buffer, + int *buf_len, + axis2_char_t **addr, + int *port) +{ + struct sockaddr_in sender_address; + int received = 0; + socklen_t sender_address_size; + + sender_address_size = sizeof(sender_address); + received = recvfrom(sock, buffer, *buf_len, 0, (struct sockaddr *)&sender_address, &sender_address_size); +#ifdef WIN32 + if (SOCKET_ERROR == received) + { + axis2_char_t buf[AXUTIL_WIN32_ERROR_BUFSIZE]; + axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf); + return AXIS2_FAILURE; + } +#else + if(received < 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE); + return AXIS2_INVALID_SOCKET; + } +#endif + if(port && addr) + { + *port = ntohs(sender_address.sin_port); + *addr = inet_ntoa(sender_address.sin_addr); + } + *buf_len = received; + return AXIS2_SUCCESS; +} + +/* + * Sends a datagram to the specified location. + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_network_handler_send_dgram( + const axutil_env_t *env, + axis2_socket_t sock, + axis2_char_t *buff, + int *buf_len, + axis2_char_t *addr, + int dest_port, + int *source_port) +{ + struct sockaddr_in recv_addr, source_addr; + int send_bytes = 0; + unsigned int recv_addr_size = 0; + socklen_t source_addr_size = sizeof(source_addr); + recv_addr_size = sizeof(recv_addr); + + memset(&recv_addr, 0, sizeof(recv_addr)); + memset(&recv_addr, 0, sizeof(source_addr)); + + recv_addr.sin_addr.s_addr = inet_addr(addr); + if(recv_addr.sin_addr.s_addr == AXIS2_INADDR_NONE) /*netinet/in.h */ + { + /* + * server may be a host name + */ + struct hostent *lphost = NULL; + lphost = gethostbyname(addr); + + if(lphost) + { + recv_addr.sin_addr.s_addr = ((struct in_addr *)lphost->h_addr)->s_addr; + } + else + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_ADDRESS, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + + recv_addr.sin_family = AF_INET; + recv_addr.sin_port = htons((axis2_unsigned_short_t)dest_port); + + send_bytes = sendto(sock, buff, *buf_len, 0, (struct sockaddr *)&recv_addr, recv_addr_size); + + getsockname(sock, (struct sockaddr *)&source_addr, &source_addr_size); + +#ifdef WIN32 + if (send_bytes == SOCKET_ERROR) + { + axis2_char_t buf[AXUTIL_WIN32_ERROR_BUFSIZE]; + axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf); + return AXIS2_FAILURE; + } +#else + if(send_bytes < 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE); + return AXIS2_FAILURE; + } +#endif + if(source_port) + { + *source_port = ntohs(source_addr.sin_port); + } + *buf_len = send_bytes; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_network_handler_bind_socket( + const axutil_env_t *env, + axis2_socket_t sock, + int port) +{ + struct sockaddr_in source_addr; + + memset(&source_addr, 0, sizeof(source_addr)); + source_addr.sin_family = AF_INET; + source_addr.sin_addr.s_addr = htonl(INADDR_ANY); + source_addr.sin_port = htons((axis2_unsigned_short_t)port); +#ifdef WIN32 + if (bind(sock, (struct sockaddr *)&source_addr, sizeof(source_addr)) == SOCKET_ERROR) + { + axis2_char_t buf[AXUTIL_WIN32_ERROR_BUFSIZE]; + axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf); + return AXIS2_FAILURE; + } +#else + if(bind(sock, (struct sockaddr *)&source_addr, sizeof(source_addr)) < 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE); + return AXIS2_INVALID_SOCKET; + } +#endif + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_socket_t AXIS2_CALL +axutil_network_hadler_create_multicast_svr_socket( + const axutil_env_t *env, + int port, + axis2_char_t *mul_addr) +{ + axis2_socket_t sock = AXIS2_INVALID_SOCKET; + struct sockaddr_in sock_addr; + struct ip_mreq mc_req; + + AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE); +#if defined(WIN32) + if (is_init_socket == 0) + { + axis2_init_socket(); + is_init_socket = 1; + } +#endif + sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + +#ifndef WIN32 + if(sock < 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE); + return AXIS2_FAILURE; + } +#else + if (sock == INVALID_SOCKET) + { + axis2_char_t buf[AXUTIL_WIN32_ERROR_BUFSIZE]; + axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf); + return AXIS2_FAILURE; + } +#endif + + /* Exec behaviour */ + AXIS2_CLOSE_SOCKET_ON_EXIT(sock); + memset(&sock_addr, 0, sizeof(sock_addr)); + + sock_addr.sin_family = AF_INET; + sock_addr.sin_addr.s_addr = htonl(INADDR_ANY); + sock_addr.sin_port = htons((axis2_unsigned_short_t)port); + + /* Bind the socket to our port number */ + if(bind(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) < 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_BIND_FAILED, AXIS2_FAILURE); + return AXIS2_INVALID_SOCKET; + } + + /* Send an IGMP request to join the multicast group */ + mc_req.imr_multiaddr.s_addr = inet_addr(mul_addr); + mc_req.imr_interface.s_addr = htonl(INADDR_ANY); +#ifdef WIN32 + if ((setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &mc_req, sizeof(mc_req))) == SOCKET_ERROR) + { + axis2_char_t buf[AXUTIL_WIN32_ERROR_BUFSIZE]; + axutil_win32_get_last_wsa_error(buf, AXUTIL_WIN32_ERROR_BUFSIZE); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, buf); + return AXIS2_FAILURE; + } +#else + if((setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mc_req, sizeof(mc_req))) < 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE); + return AXIS2_FAILURE; + } +#endif + return sock; +} + |