If argument `ip_addr' is NULL `any' address will be used. Returns
the created socket or -1 on error. */
-int silc_net_create_server(int port, char *ip_addr)
+int silc_net_create_server(int port, const char *ip_addr)
{
int sock, rval;
struct sockaddr_in server;
SILC_LOG_DEBUG(("Creating a new server listener"));
/* Create the socket */
- sock = socket(PF_INET, SOCK_STREAM, 0);
+ sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
SILC_LOG_ERROR(("Cannot create socket: %s", strerror(errno)));
return -1;
/* Set the socket information for bind() */
memset(&server, 0, sizeof(server));
- server.sin_family = PF_INET;
+ server.sin_family = AF_INET;
if (port)
server.sin_port = htons(port);
/* Convert IP address to network byte order */
- if (ip_addr)
+ if (ip_addr) {
silc_net_addr2bin(ip_addr, (unsigned char *)&server.sin_addr.s_addr, len);
+ }
else
server.sin_addr.s_addr = INADDR_ANY;
/* Bind the server socket */
rval = bind(sock, (struct sockaddr *)&server, sizeof(server));
if (rval < 0) {
- SILC_LOG_ERROR(("Cannot bind socket: %s", strerror(errno)));
+ SILC_LOG_DEBUG(("Cannot bind socket: %s", strerror(errno)));
return -1;
}
socket or -1 on error. This blocks the process while trying to create
the connection. */
-int silc_net_create_connection(int port, char *host)
+int silc_net_create_connection(const char *local_ip, int port,
+ const char *host)
{
int sock, rval;
struct hostent *dest;
/* Set socket information */
memset(&desthost, 0, sizeof(desthost));
desthost.sin_port = htons(port);
- desthost.sin_family = PF_INET;
+ desthost.sin_family = AF_INET;
memcpy(&desthost.sin_addr, dest->h_addr_list[0], sizeof(desthost.sin_addr));
/* Create the connection socket */
- sock = socket(PF_INET, SOCK_STREAM, 0);
+ sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
SILC_LOG_ERROR(("Cannot create socket: %s", strerror(errno)));
return -1;
}
+ /* Bind to the local address if provided */
+ if (local_ip) {
+ struct sockaddr_in local;
+ int local_len = sizeof(local.sin_addr);
+
+ /* Set the socket information for bind() */
+ memset(&local, 0, sizeof(local));
+ local.sin_family = AF_INET;
+
+ /* Convert IP address to network byte order */
+ silc_net_addr2bin(local_ip, (unsigned char *)&local.sin_addr.s_addr,
+ local_len);
+
+ /* Bind the local socket */
+ rval = bind(sock, (struct sockaddr *)&local, sizeof(local));
+ if (rval < 0) {
+ SILC_LOG_ERROR(("Cannot connect to remote host: "
+ "cannot bind socket: %s", strerror(errno)));
+ return -1;
+ }
+ }
+
/* Connect to the host */
rval = connect(sock, (struct sockaddr *)&desthost, sizeof(desthost));
if (rval < 0) {
connection returns directly. To get the result of the connect() one
must select() the socket and read the result after it's ready. */
-int silc_net_create_connection_async(int port, char *host)
+int silc_net_create_connection_async(const char *local_ip, int port,
+ const char *host)
{
int sock, rval;
struct hostent *dest;
/* Set socket information */
memset(&desthost, 0, sizeof(desthost));
desthost.sin_port = htons(port);
- desthost.sin_family = PF_INET;
+ desthost.sin_family = AF_INET;
memcpy(&desthost.sin_addr, dest->h_addr_list[0], sizeof(desthost.sin_addr));
/* Create the connection socket */
- sock = socket(PF_INET, SOCK_STREAM, 0);
+ sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
SILC_LOG_ERROR(("Cannot create socket: %s", strerror(errno)));
return -1;
}
+ /* Bind to the local address if provided */
+ if (local_ip) {
+ struct sockaddr_in local;
+ int local_len = sizeof(local.sin_addr);
+
+ /* Set the socket information for bind() */
+ memset(&local, 0, sizeof(local));
+ local.sin_family = AF_INET;
+
+ /* Convert IP address to network byte order */
+ silc_net_addr2bin(local_ip, (unsigned char *)&local.sin_addr.s_addr,
+ local_len);
+
+ /* Bind the local socket */
+ rval = bind(sock, (struct sockaddr *)&local, sizeof(local));
+ if (rval < 0) {
+ SILC_LOG_ERROR(("Cannot connect to remote host: "
+ "cannot bind socket: %s", strerror(errno)));
+ return -1;
+ }
+ }
+
/* Set the socket to non-blocking mode */
silc_net_set_socket_nonblock(sock);
/* Converts the IP number string from numbers-and-dots notation to
binary form. */
-bool silc_net_addr2bin(const char *addr, unsigned char *bin,
- uint32 bin_len)
+bool silc_net_addr2bin(const char *addr, void *bin, uint32 bin_len)
{
struct in_addr tmp;
int ret;
if (bin_len < 4)
return FALSE;
- SILC_PUT32_LSB(tmp.s_addr, bin);
-
+ memcpy(bin, (unsigned char *)&tmp.s_addr, 4);
return ret != 0;
}