/* | |
* 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]; | |
AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE); | |
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; | |
unsigned int 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; | |
unsigned int 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; | |
} | |