/* Sets up the object. - ... */ RC_TYPE ip_initialize(IP_SOCKET *p_self) { RC_TYPE rc = RC_OK; if (p_self->initialized == TRUE) { return RC_OK; } do { // res_init(); rc = os_ip_support_startup(); if (rc != RC_OK) { break; } /*remote addres */ if (p_self->p_remote_host_name != NULL) { unsigned long addr = 0; HOSTENT* p_remotehost = (HOSTENT*) gethostbyname(p_self->p_remote_host_name); if (p_remotehost == NULL) { rc = os_convert_ip_to_inet_addr(&addr, p_self->p_remote_host_name); if (rc != RC_OK) { DBG_PRINTF((LOG_WARNING,MODULE_TAG "Error '0x%x' resolving host name '%s'\n", os_get_socket_error(), p_self->p_remote_host_name)); rc = RC_IP_INVALID_REMOTE_ADDR; break; } } p_self->remote_addr.sin_family = AF_INET; p_self->remote_addr.sin_port = htons(p_self->port); p_self->remote_addr.sin_addr.s_addr = (addr == 0) ? *((unsigned long *)p_remotehost->h_addr_list[0]) : addr; } } while(0); if (rc != RC_OK) { ip_shutdown(p_self); } else { p_self->initialized = TRUE; } return rc; }
/* Receive data into user's buffer. return if the max len has been received if a timeout occures In p_recv_len the total number of bytes are returned. Note: if the recv_len is bigger than 0, no error is returned. */ RC_TYPE ip_recv(IP_SOCKET *p_self, char *p_buf, int max_recv_len, int *p_recv_len) { RC_TYPE rc = RC_OK; int remaining_buf_len = max_recv_len; int total_recv_len = 0; int recv_len = 0; if (p_self == NULL || p_buf == NULL || p_recv_len == NULL) { return RC_INVALID_POINTER; } if (!p_self->initialized) { return RC_IP_OBJECT_NOT_INITIALIZED; } while (remaining_buf_len > 0) { int chunk_size = remaining_buf_len > IP_DEFAULT_READ_CHUNK_SIZE ? IP_DEFAULT_READ_CHUNK_SIZE : remaining_buf_len; recv_len = recv(p_self->socket, p_buf + total_recv_len, chunk_size, 0); if (recv_len < 0) { { DBG_PRINTF((LOG_WARNING, MODULE_TAG "Error 0x%x in recv()\n", os_get_socket_error())); rc = RC_IP_RECV_ERROR; } break; } if (recv_len == 0) { if (total_recv_len == 0) { rc = RC_IP_RECV_ERROR; } break; } total_recv_len += recv_len; remaining_buf_len = max_recv_len - total_recv_len; } *p_recv_len = total_recv_len; return rc; }
int ip_send(ip_sock_t *ip, const char *buf, int len) { ASSERT(ip); if (!ip->initialized) return RC_IP_OBJECT_NOT_INITIALIZED; if (send(ip->socket, buf, len, 0) == -1) { int code = os_get_socket_error(); logit(LOG_WARNING, "Network error while sending query/update: %s", strerror(code)); return RC_IP_SEND_ERROR; } return 0; }
/* Receive data into user's buffer. return if the max len has been received if a timeout occures In p_recv_len the total number of bytes are returned. Note: if the recv_len is bigger than 0, no error is returned. */ int ip_recv(ip_sock_t *p_self, char *p_buf, int max_recv_len, int *p_recv_len) { int rc = 0; int remaining_buf_len = max_recv_len; int total_recv_len = 0; int recv_len = 0; if (p_self == NULL || p_buf == NULL || p_recv_len == NULL) { return RC_INVALID_POINTER; } if (!p_self->initialized) { return RC_IP_OBJECT_NOT_INITIALIZED; } while (remaining_buf_len > 0) { int chunk_size = remaining_buf_len > IP_DEFAULT_READ_CHUNK_SIZE ? IP_DEFAULT_READ_CHUNK_SIZE : remaining_buf_len; recv_len = recv(p_self->socket, p_buf + total_recv_len, chunk_size, 0); if (recv_len < 0) { int code = os_get_socket_error(); logit(LOG_WARNING, "Network error while waiting for reply: %s", strerror(code)); rc = RC_IP_RECV_ERROR; break; } if (recv_len == 0) { if (total_recv_len == 0) { rc = RC_IP_RECV_ERROR; } break; } total_recv_len += recv_len; remaining_buf_len = max_recv_len - total_recv_len; } *p_recv_len = total_recv_len; return rc; }
/* Receive data into user's buffer. return if the max len has been received if a timeout occures In p_recv_len the total number of bytes are returned. Note: if the recv_len is bigger than 0, no error is returned. */ int ip_recv(ip_sock_t *ip, char *buf, int len, int *recv_len) { int rc = 0; int remaining_bytes = len; int total_bytes = 0; ASSERT(ip); ASSERT(buf); ASSERT(recv_len); if (!ip->initialized) return RC_IP_OBJECT_NOT_INITIALIZED; while (remaining_bytes > 0) { int bytes; int chunk_size = remaining_bytes > IP_DEFAULT_READ_CHUNK_SIZE ? IP_DEFAULT_READ_CHUNK_SIZE : remaining_bytes; bytes = recv(ip->socket, buf + total_bytes, chunk_size, 0); if (bytes < 0) { int code = os_get_socket_error(); logit(LOG_WARNING, "Network error while waiting for reply: %s", strerror(code)); rc = RC_IP_RECV_ERROR; break; } if (bytes == 0) { if (total_bytes == 0) rc = RC_IP_RECV_ERROR; break; } total_bytes += bytes; remaining_bytes = len - total_bytes; } *recv_len = total_bytes; return rc; }
int ip_send(ip_sock_t *p_self, const char *p_buf, int len) { if (p_self == NULL) { return RC_INVALID_POINTER; } if (!p_self->initialized) { return RC_IP_OBJECT_NOT_INITIALIZED; } if (send(p_self->socket, (char *)p_buf, len, 0) == -1) { int code = os_get_socket_error(); logit(LOG_WARNING, "Network error while sending query/update: %s", strerror(code)); return RC_IP_SEND_ERROR; } return 0; }
RC_TYPE ip_send(IP_SOCKET *p_self, const char *p_buf, int len) { if (p_self == NULL) { return RC_INVALID_POINTER; } if (!p_self->initialized) { return RC_IP_OBJECT_NOT_INITIALIZED; } if( send(p_self->socket, (char*) p_buf, len, 0) == SOCKET_ERROR ) { DBG_PRINTF((LOG_WARNING,MODULE_TAG "Error 0x%x in send()\n", os_get_socket_error())); return RC_IP_SEND_ERROR; } return RC_OK; }
/* Get the IP address from interface */ static RC_TYPE do_ip_check_interface(DYN_DNS_CLIENT *p_self) { struct ifreq ifr; in_addr_t new_ip; char *new_ip_str; int i; if (p_self == NULL) { return RC_INVALID_POINTER; } if (p_self->check_interface) { logit(LOG_INFO, MODULE_TAG "Checking for IP# change, querying interface %s", p_self->check_interface); int sd = socket(PF_INET, SOCK_DGRAM, 0); if (sd < 0) { int code = os_get_socket_error(); logit(LOG_WARNING, MODULE_TAG "Failed opening network socket: %s", strerror(code)); return RC_IP_OS_SOCKET_INIT_FAILED; } memset(&ifr, 0, sizeof(struct ifreq)); ifr.ifr_addr.sa_family = AF_INET; snprintf(ifr.ifr_name, IFNAMSIZ, p_self->check_interface); if (ioctl(sd, SIOCGIFADDR, &ifr) != -1) { new_ip = ntohl(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr); new_ip_str = inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr); } else { int code = os_get_socket_error(); logit(LOG_ERR, MODULE_TAG "Failed reading IP address of interface %s: %s", p_self->check_interface, strerror(code)); return RC_ERROR; } close(sd); } else { return RC_ERROR; } if (IN_ZERONET(new_ip) || IN_LOOPBACK(new_ip) || IN_LINKLOCAL(new_ip) || IN_MULTICAST(new_ip) || IN_EXPERIMENTAL(new_ip)) { logit(LOG_WARNING, MODULE_TAG "Interface %s has invalid IP# %s", p_self->check_interface, new_ip_str); return RC_ERROR; } int anychange = 0; for (i = 0; i < p_self->info_count; i++) { DYNDNS_INFO_TYPE *info = &p_self->info[i]; info->my_ip_has_changed = strcmp(info->my_ip_address.name, new_ip_str) != 0; if (info->my_ip_has_changed) { anychange++; strcpy(info->my_ip_address.name, new_ip_str); } } if (!anychange) { logit(LOG_INFO, MODULE_TAG "No IP# change detected, still at %s", new_ip_str); } return RC_OK; }
/* Sets up the object. */ int ip_init(ip_sock_t *ip) { int rc = 0; struct ifreq ifr; struct sockaddr_in *addrp = NULL; ASSERT(ip); if (ip->initialized == 1) return 0; do { TRY(os_ip_support_startup()); /* local bind, to interface */ if (ip->ifname) { int sd = socket(PF_INET, SOCK_DGRAM, 0); if (sd < 0) { int code = os_get_socket_error(); logit(LOG_WARNING, "Failed opening network socket: %s", strerror(code)); rc = RC_IP_OS_SOCKET_INIT_FAILED; break; } memset(&ifr, 0, sizeof(struct ifreq)); strlcpy(ifr.ifr_name, ip->ifname, IFNAMSIZ); if (ioctl(sd, SIOCGIFADDR, &ifr) != -1) { ip->local_addr.sin_family = AF_INET; ip->local_addr.sin_port = htons(0); addrp = (struct sockaddr_in *)&(ifr.ifr_addr); ip->local_addr.sin_addr.s_addr = addrp->sin_addr.s_addr; ip->bound = 1; logit(LOG_INFO, "Bound to interface %s (IP# %s)", ip->ifname, inet_ntoa(ip->local_addr.sin_addr)); } else { int code = os_get_socket_error(); logit(LOG_ERR, "Failed reading IP address of interface %s: %s", ip->ifname, strerror(code)); ip->bound = 0; } close(sd); } /* remote address */ if (ip->p_remote_host_name) { int s; char port[10]; struct addrinfo hints, *result; /* Clear DNS cache before calling getaddrinfo(). */ res_init(); /* Obtain address(es) matching host/port */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_INET; /* Use AF_UNSPEC to allow IPv4 or IPv6 */ hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ snprintf(port, sizeof(port), "%d", ip->port); s = getaddrinfo(ip->p_remote_host_name, port, &hints, &result); if (s != 0 || !result) { logit(LOG_WARNING, "Failed resolving hostname %s: %s", ip->p_remote_host_name, gai_strerror(s)); rc = RC_IP_INVALID_REMOTE_ADDR; break; } /* XXX: Here we should iterate over all of the records returned by * getaddrinfo(), but with this code here in ip.c and connect() being * in tcp.c that's hardly feasible. Needs refactoring! --Troglobit */ ip->remote_addr = *result->ai_addr; ip->remote_len = result->ai_addrlen; freeaddrinfo(result); /* No longer needed */ } } while (0); if (rc) { ip_exit(ip); return rc; } ip->initialized = 1; return 0; }
/* Sets up the object. - ... */ int tcp_initialize(tcp_sock_t *p_self, char *msg) { int rc; struct timeval sv; int svlen = sizeof(sv); char host[NI_MAXHOST]; do { local_set_params(p_self); /*call the super */ rc = ip_initialize(&p_self->super); if (rc != 0) { break; } /* local object initalizations */ if (p_self->super.type == TYPE_TCP) { p_self->super.socket = socket(AF_INET, SOCK_STREAM, 0); if (p_self->super.socket == -1) { int code = os_get_socket_error(); logit(LOG_ERR, "Error creating client socket: %s", strerror(code)); rc = RC_IP_SOCKET_CREATE_ERROR; break; } /* Call to socket() OK, allow tcp_shutdown() to run to * prevent socket leak if any of the below calls fail. */ p_self->initialized = 1; if (p_self->super.bound == 1) { if (bind (p_self->super.socket, (struct sockaddr *)&p_self->super.local_addr, sizeof(struct sockaddr_in)) < 0) { int code = os_get_socket_error(); logit(LOG_WARNING, "Failed binding client socket to local address: %s", strerror(code)); rc = RC_IP_SOCKET_BIND_ERROR; break; } } } else { p_self->initialized = 1; /* Allow tcp_shutdown() to run. */ rc = RC_IP_BAD_PARAMETER; } /* set timeouts */ sv.tv_sec = p_self->super.timeout / 1000; /* msec to sec */ sv.tv_usec = (p_self->super.timeout % 1000) * 1000; /* reminder to usec */ setsockopt(p_self->super.socket, SOL_SOCKET, SO_RCVTIMEO, &sv, svlen); setsockopt(p_self->super.socket, SOL_SOCKET, SO_SNDTIMEO, &sv, svlen); if (!getnameinfo (&p_self->super.remote_addr, p_self->super.remote_len, host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST)) { logit(LOG_INFO, "%s, connecting to %s(%s)", msg, p_self->super.p_remote_host_name, host); } if (0 != connect(p_self->super.socket, &p_self->super.remote_addr, p_self->super.remote_len)) { int code = os_get_socket_error(); logit(LOG_WARNING, "Failed connecting to remote server: %s", strerror(code)); rc = RC_IP_CONNECT_FAILED; break; } } while (0); if (rc != 0) { tcp_shutdown(p_self); return rc; } return 0; }