int __cdecl #else int #endif main( int argc, char ** argv) { sw_discovery discovery; sw_discovery_oid oid; sw_result err; err = sw_discovery_init(&discovery); sw_check_okay(err, exit); if (argc != 4) { fprintf(stderr, "usage: mDNSBrowse <name> <rrtype> <rrclass>\n"); return -1; } err = sw_discovery_query_record(discovery, 0, 0, argv[1], atoi(argv[2]), atoi(argv[3]), query_record_reply, NULL, &oid); sw_check_okay(err, exit); err = sw_discovery_run(discovery); sw_check_okay(err, exit); exit: return err; }
int __cdecl #else int #endif main( int argc, char ** argv) { sw_discovery discovery; sw_discovery_oid oid; sw_result err; err = sw_discovery_init(&discovery); sw_check_okay(err, exit); if (argc != 2) { fprintf(stderr, "usage: mDNSBrowse <type>\n"); return -1; } err = sw_discovery_browse(discovery, 0, argv[1], NULL, my_browser, NULL, &oid); sw_check_okay(err, exit); err = sw_discovery_run(discovery); sw_check_okay(err, exit); exit: return err; }
sw_result sw_ipv4_address_init_from_this_host( sw_ipv4_address * self) { #if defined(__VXWORKS__) sw_int8 current_addr[INET_ADDR_LEN]; if (ifAddrGet(sysEnetNameGet(), current_addr) != OK) { sw_debug(SW_LOG_ERROR, "sw_ipv4_address_init_from_this_host", "ifAddrGet() failed\n"); return SW_E_INIT; } self->m_addr = inet_addr(current_addr); #else struct sockaddr_in addr; sw_result err; sw_sockdesc_t desc; sw_socklen_t len; desc = socket(AF_INET, SOCK_DGRAM, 0); sw_check(desc != SW_INVALID_SOCKET, exit, err = SW_E_UNKNOWN); sw_memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr("192.168.1.1"); addr.sin_port = htons(5555); err = connect(desc, (struct sockaddr*) &addr, sizeof(addr)); sw_check_okay(err, exit); sw_memset(&addr, 0, sizeof(addr)); len = sizeof(addr); err = getsockname(desc, (struct sockaddr*) &addr, &len); sw_check_okay(err, exit); self->m_addr = addr.sin_addr.s_addr; #endif exit: if (desc != SW_INVALID_SOCKET) { sw_close_socket(desc); } if (err != SW_OKAY) { err = sw_ipv4_address_init_from_address(self, sw_ipv4_address_loopback()); } return err; }
sw_result sw_corby_channel_init( sw_corby_channel * self, struct _sw_corby_orb * orb, sw_socket socket, sw_socket_options options, sw_size_t bufsize) { sw_result err; *self = (sw_corby_channel) sw_malloc(sizeof(struct _sw_corby_channel)); err = sw_translate_error(*self, SW_E_MEM); sw_check_okay_log(err, exit); sw_memset(*self, 0, sizeof(struct _sw_corby_channel)); if (options) { err = sw_socket_set_options(socket, options); sw_check_okay(err, exit); } err = sw_ipv4_address_init(&(*self)->m_from); sw_check_okay(err, exit); (*self)->m_orb = orb; (*self)->m_socket = socket; (*self)->m_refs = 1; (*self)->m_state = Waiting; err = sw_corby_message_init(&(*self)->m_message); sw_check_okay(err, exit); err = sw_corby_buffer_init_with_size(&(*self)->m_send_buffer, (bufsize) ? bufsize : SW_CORBY_CHANNEL_DEFAULT_BUFFER_SIZE); sw_check_okay(err, exit); err = sw_corby_buffer_init_with_size(&(*self)->m_read_buffer, (bufsize) ? bufsize : SW_CORBY_CHANNEL_DEFAULT_BUFFER_SIZE); sw_check_okay(err, exit); exit: if (err && *self) { sw_corby_channel_fina(*self); } return err; }
static sw_result sw_socket_udp_recvfrom( sw_socket self, sw_octets buffer, sw_size_t max, sw_size_t * len, sw_ipv4_address * from, sw_port * from_port, sw_ipv4_address * dest, sw_uint32 * interface_index) { struct sockaddr_in from_addr; struct in_addr dest_addr; sw_result err; err = sw_socket_udp_really_recvfrom(self, buffer, max, len, (struct sockaddr*) &from_addr, sizeof(from_addr), &dest_addr, interface_index); sw_check_okay(err, exit); sw_ipv4_address_init_from_saddr(from, from_addr.sin_addr.s_addr); *from_port = ntohs(from_addr.sin_port); if (dest) { sw_ipv4_address_init_from_saddr(dest, dest_addr.s_addr); } exit: return err; }
static sw_result sw_socket_tcp_close( sw_socket self) { int res; sw_result err; sw_debug(SW_LOG_VERBOSE, "sw_socket_tcp_close() : fd = %d\n", self->m_desc); #if defined(WIN32) res = shutdown(self->m_desc, SD_SEND); #else res = shutdown(self->m_desc, 2); /* * Patch from Michael ([email protected]) * * we should only fail here if errno isn't ENOTCONN or ENOENT ( Solaris 9 sets errno to ENOENT * if the socket isn't connected, despite the man page for shutdown saying it would use * ENOTCONN ) */ err = sw_translate_error((res == 0) || (errno == ENOENT) || (errno == ENOTCONN), sw_socket_errno()); sw_check_okay(err, exit); #endif res = sw_close_socket(self->m_desc); err = sw_translate_error(res == 0, sw_socket_errno()); sw_check_okay_log(err, exit); exit: self->m_connected = SW_FALSE; return err; }
sw_result sw_multicast_socket_super_init( sw_socket self) { int opt = 1; int res; sw_result err; err = sw_socket_init(self, SW_FALSE, &sw_socket_udp_connect, &sw_socket_udp_send, &sw_socket_udp_sendto, &sw_socket_udp_recv, &sw_socket_udp_recvfrom, &sw_socket_udp_close); sw_check_okay(err, exit); self->m_desc = socket(AF_INET, SOCK_DGRAM, 0); err = sw_translate_error(self->m_desc != SW_INVALID_SOCKET, sw_socket_errno()); sw_check_okay_log(err, exit); #if defined(__APPLE__) || defined(__VXWORKS__) || defined(__FreeBSD__) || defined(__NetBSD__) res = setsockopt(self->m_desc, SOL_SOCKET, SO_REUSEPORT, (char*) &opt, sizeof(opt)); #else res = setsockopt(self->m_desc, SOL_SOCKET, SO_REUSEADDR, (char*) &opt, sizeof(opt)); #endif err = sw_translate_error(res == 0, sw_socket_errno()); sw_check_okay_log(err, exit); exit: return err; }
static sw_result HOWL_API my_resolver( sw_discovery discovery, sw_discovery_oid oid, sw_uint32 interface_index, sw_const_string name, sw_const_string type, sw_const_string domain, sw_ipv4_address address, sw_port port, sw_octets text_record, sw_uint32 text_record_len, sw_opaque_t extra) { sw_text_record_iterator it; sw_int8 name_buf[16]; sw_int8 key[SW_TEXT_RECORD_MAX_LEN]; sw_int8 sval[SW_TEXT_RECORD_MAX_LEN]; sw_uint8 oval[SW_TEXT_RECORD_MAX_LEN]; sw_uint32 oval_len; sw_result err = SW_OKAY; sw_discovery_cancel(discovery, oid); fprintf(stderr, "resolve reply: 0x%x %s %s %s %s %d\n", interface_index, name, type, domain, sw_ipv4_address_name(address, name_buf, 16), port); if ((text_record_len > 0) && (text_record) && (*text_record != '\0')) { err = sw_text_record_iterator_init(&it, text_record, text_record_len); sw_check_okay(err, exit); while (sw_text_record_iterator_next(it, key, oval, &oval_len) == SW_OKAY) { fprintf(stderr, "Txt: [%s]=[%s] - (%d bytes)\n", key, oval, oval_len); } err = sw_text_record_iterator_fina(it); sw_check_okay(err, exit); } exit: return err; }
sw_result sw_socket_accept( sw_socket self, sw_socket * socket) { struct sockaddr_in addr; sw_sockdesc_t desc; sw_socklen_t len; int nodelay = 1; struct linger l; int res; sw_result err; len = sizeof(addr); sw_memset(&addr, 0, sizeof(addr)); desc = accept(self->m_desc, (struct sockaddr*) &addr, &len); err = sw_translate_error(desc != SW_INVALID_SOCKET, sw_socket_errno()); sw_check_okay(err, exit); res = setsockopt(desc, IPPROTO_TCP, TCP_NODELAY, (char*) &nodelay, sizeof(nodelay)); err = sw_translate_error(res == 0, sw_socket_errno()); sw_check_okay_log(err, exit); l.l_onoff = 0; l.l_linger = 0; res = setsockopt(desc, SOL_SOCKET, SO_LINGER, (char*) &l, sizeof(l)); err = sw_translate_error(res == 0, sw_socket_errno()); sw_check_okay_log(err, exit); err = sw_tcp_socket_init_with_desc(socket, desc); sw_check_okay(err, exit); exit: return err; }
sw_result sw_tcp_socket_super_init_with_desc( sw_socket self, sw_sockdesc_t desc) { sw_result err; err = sw_socket_init(self, SW_FALSE, &sw_socket_tcp_connect, &sw_socket_tcp_send, &sw_socket_tcp_sendto, &sw_socket_tcp_recv, &sw_socket_tcp_recvfrom, &sw_socket_tcp_close); sw_check_okay(err, exit); self->m_desc = desc; exit: return err; }
sw_result sw_udp_socket_super_init( sw_socket self) { sw_result err; err = sw_socket_init(self, SW_FALSE, &sw_socket_udp_connect, &sw_socket_udp_send, &sw_socket_udp_sendto, &sw_socket_udp_recv, &sw_socket_udp_recvfrom, &sw_socket_udp_close); sw_check_okay(err, exit); self->m_desc = socket(AF_INET, SOCK_DGRAM, 0); err = sw_translate_error(self->m_desc != SW_INVALID_SOCKET, sw_socket_errno()); sw_check_okay_log(err, exit); exit: return err; }
sw_result sw_socket_join_multicast_group( sw_socket self, sw_ipv4_address local_address, sw_ipv4_address multicast_address, sw_uint32 ttl) { struct in_addr addr; struct ip_mreq mreq; #if defined(__sun) || defined(__VXWORKS__) || defined(__NetBSD__) || defined(__OpenBSD__) sw_uint8 real_ttl = (sw_uint8) ttl; #else sw_uint32 real_ttl = ttl; #endif int res; sw_result err; /* initialize the group membership */ sw_memset(&addr, 0, sizeof(addr)); addr.s_addr = sw_ipv4_address_saddr(local_address); sw_memset(&mreq, 0, sizeof(mreq)); #if defined(__VXWORKS__) /* VxWorks doesn't like it if we try and use INADDR_ANY for use in setting up multicast sockets. So we please it. */ if (sw_ipv4_address_is_any(local_address)) { sw_ipv4_address current_address; err = sw_ipv4_address_init_from_this_host(¤t_address); sw_check_okay(err, exit); mreq.imr_interface.s_addr = sw_ipv4_address_saddr(current_address); } else { mreq.imr_interface = addr; } #else mreq.imr_interface = addr; #endif mreq.imr_multiaddr.s_addr = sw_ipv4_address_saddr(multicast_address); res = setsockopt(self->m_desc, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*) &mreq, sizeof(mreq)); err = sw_translate_error(res == 0, sw_socket_errno()); sw_check_okay_log(err, exit); res = setsockopt(self->m_desc, IPPROTO_IP, IP_MULTICAST_IF, (char*) &addr, sizeof(addr)); err = sw_translate_error(res == 0, sw_socket_errno()); sw_check_okay_log(err, exit); res = setsockopt(self->m_desc, IPPROTO_IP, IP_TTL, (char*) &ttl, sizeof(ttl)); err = sw_translate_error(res == 0, sw_socket_errno()); sw_check_okay_log(err, exit); res = setsockopt(self->m_desc, IPPROTO_IP, IP_MULTICAST_TTL, (char*) &real_ttl, sizeof(real_ttl)); err = sw_translate_error(res == 0, sw_socket_errno()); sw_check_okay_log(err, exit); exit: return err; }
sw_result sw_corby_channel_recv( sw_corby_channel self, sw_salt * salt, sw_corby_message * message, sw_uint32 * request_id, sw_string * op, sw_uint32 * op_len, sw_corby_buffer * buffer, sw_uint8 * endian, sw_bool block) { static sw_const_string message_type[] = { "Request", "Reply", "CancelRequest", "LocateRequest", "LocateReply", "CloseConnection", "MessageError" }; sw_size_t buflen; sw_size_t len; sw_result err = SW_OKAY; SW_UNUSED_PARAM(request_id); sw_debug(SW_LOG_VERBOSE, "entering sw_corby_channel_recv()\n"); if (self->m_state == Waiting) { self->m_message->m_header = NULL; } /* * side effect the salt reference */ if (salt) { (*salt) = self->m_orb->m_salt; } while (SW_TRUE) { buflen = (self->m_read_buffer->m_eptr - self->m_read_buffer->m_bptr); *buffer = NULL; if (message) { *message = NULL; } sw_debug(SW_LOG_VERBOSE, " %s %s, buffer(m_base = %x, m_bptr = %x, m_eptr = %x, m_end = %x, buflen = %d)\n", (block) ? "block" : "!block", (self->m_message->m_header) ? "message_header" : "!message_header", self->m_read_buffer->m_base, self->m_read_buffer->m_bptr, self->m_read_buffer->m_eptr, self->m_read_buffer->m_end, buflen); /* beginning a new message */ if (self->m_message->m_header == NULL) { self->m_state = Reading; /* do we need to shift stuff down and reset pointers? */ if (buflen && (self->m_read_buffer->m_bptr != self->m_read_buffer->m_base)) { sw_debug(SW_LOG_VERBOSE, " shifting buffer pointers %d bytes\n", buflen); sw_memcpy(self->m_read_buffer->m_base, self->m_read_buffer->m_bptr, buflen); } self->m_read_buffer->m_bptr = self->m_read_buffer->m_base; self->m_read_buffer->m_eptr = self->m_read_buffer->m_base + buflen; /* do we have enough to read a message header */ if (buflen >= sizeof(struct _sw_swop_message_header)) { self->m_message->m_header = (sw_swop_message_header*) self->m_read_buffer->m_base; sw_debug(SW_LOG_VERBOSE, " SWOP magic = %c %c %c %c\n", self->m_message->m_header->m_magic[0], self->m_message->m_header->m_magic[1], self->m_message->m_header->m_magic[2], self->m_message->m_header->m_magic[3]); /* check magic string */ sw_check ( ((self->m_message->m_header->m_magic[0] == 'S') && (self->m_message->m_header->m_magic[1] == 'W') && (self->m_message->m_header->m_magic[2] == 'O') && (self->m_message->m_header->m_magic[3] == 'P')), exit, err = SW_E_CORBY_BAD_MESSAGE ); sw_debug(SW_LOG_VERBOSE, " SWOP version = %d %d\n", self->m_message->m_header->m_major, self->m_message->m_header->m_minor); /* check version number */ sw_check ( ((self->m_message->m_header->m_major <= SW_SWOP_MAJOR) && (self->m_message->m_header->m_minor <= SW_SWOP_MINOR)), exit, err = SW_E_CORBY_BAD_VERSION ); sw_debug(SW_LOG_VERBOSE, " SWOP endian = %d\n", self->m_message->m_header->m_endian); sw_debug(SW_LOG_VERBOSE, " SWOP message type = %s\n", message_type[self->m_message->m_header->m_msg_type]); /* fix size */ if (self->m_message->m_header->m_endian != SW_ENDIAN) { self->m_message->m_header->m_msg_size = SW_SWAP32(self->m_message->m_header->m_msg_size); } sw_debug(SW_LOG_VERBOSE, " SWOP size = %d\n", self->m_message->m_header->m_msg_size); /* make sure we have enough buffer space */ if (self->m_message->m_header->m_msg_size > ((self->m_read_buffer->m_end - self->m_read_buffer->m_base) - sizeof(struct _sw_swop_message_header))) { sw_uint32 new_size; new_size = self->m_message->m_header->m_msg_size + sizeof(struct _sw_swop_message_header); self->m_read_buffer->m_base = (sw_octets) sw_realloc(self->m_read_buffer->m_base, new_size); sw_check(self->m_read_buffer->m_base, exit, err = SW_E_MEM); self->m_read_buffer->m_bptr = self->m_read_buffer->m_base; self->m_read_buffer->m_eptr = self->m_read_buffer->m_base + buflen; self->m_read_buffer->m_end = self->m_read_buffer->m_base + new_size; self->m_message->m_header = (struct _sw_swop_message_header*) self->m_read_buffer->m_base; } self->m_read_buffer->m_bptr += sizeof(struct _sw_swop_message_header); buflen -= sizeof(struct _sw_swop_message_header); } } /* do we have the whole message? */ if (self->m_message->m_header && (self->m_message->m_header->m_msg_size <= buflen)) { /* * we've read the whole message, so we're now * waiting for a new message */ self->m_state = Waiting; /* side effect endian */ if (endian) { *endian = self->m_message->m_header->m_endian; } sw_corby_channel_did_read(self, self->m_read_buffer->m_base, self->m_message->m_header->m_msg_size + SW_SWOP_HEADER_SIZE); switch (self->m_message->m_header->m_msg_type) { case SW_SWOP_REQUEST: return sw_corby_channel_parse_request(self, message, op, op_len, buffer); case SW_SWOP_REPLY: return sw_corby_channel_parse_reply(self, message, buffer); case SW_SWOP_CANCEL_REQUEST: return sw_corby_channel_parse_cancel_request(self, message, buffer); case SW_SWOP_LOCATE_REQUEST: return sw_corby_channel_parse_locate_request(self, message, buffer); case SW_SWOP_LOCATE_REPLY: return sw_corby_channel_parse_locate_reply(self, message, buffer); case SW_SWOP_CLOSE_CONNECTION: return sw_corby_channel_parse_close_connection(self, message, buffer); default: return sw_corby_channel_message_error(self); } } /* if we get here, then we need to read */ if (block) { err = sw_socket_recvfrom(self->m_socket, self->m_read_buffer->m_eptr, self->m_read_buffer->m_end - self->m_read_buffer->m_eptr, &len, &self->m_from, &self->m_from_port, NULL, NULL); sw_check_okay(err, exit); /* * returning 0 is fair because the socket might have been set up * in non-blocking mode. so if len == 0, we just return from * this function gracefully */ if (len > 0) { self->m_read_buffer->m_eptr += len; buflen = (self->m_read_buffer->m_eptr - self->m_read_buffer->m_bptr); } else { break; } } else { break; } } exit: return err; }
sw_result sw_corby_channel_start_reply( sw_corby_channel self, sw_corby_buffer * buffer, sw_uint32 request_id, sw_corby_reply_status status) { sw_result err; /* * don't do this if this guy isn't expecting a reply */ sw_check(self->m_message->m_body.m_request_header.m_reply_expected, exit, err = SW_E_UNKNOWN); /* blop the SWOP message header */ err = sw_corby_channel_message_header(self, SW_SWOP_REPLY); sw_check_okay(err, exit); /* service context list */ err = sw_corby_buffer_put_uint32(self->m_send_buffer, 0); sw_check_okay(err, exit); /* request id */ err = sw_corby_buffer_put_uint32(self->m_send_buffer, request_id); sw_check_okay(err, exit); /* status */ switch (status) { case SW_CORBY_NO_EXCEPTION: err = sw_corby_buffer_put_uint32(self->m_send_buffer, SW_CORBY_NO_EXCEPTION); sw_check_okay(err, exit); break; case SW_CORBY_SYSTEM_EXCEPTION: err = sw_corby_buffer_put_uint32(self->m_send_buffer, SW_CORBY_SYSTEM_EXCEPTION); sw_check_okay(err, exit); break; case SW_CORBY_USER_EXCEPTION: err = sw_corby_buffer_put_uint32(self->m_send_buffer, SW_CORBY_USER_EXCEPTION); sw_check_okay(err, exit); break; case SW_CORBY_LOCATION_FORWARD: /* unhandled */ break; } *buffer = self->m_send_buffer; exit: if (err != SW_OKAY) { *buffer = NULL; } return err; }
sw_result sw_corby_channel_start_request( sw_corby_channel self, sw_const_corby_profile profile, sw_corby_buffer * buffer, sw_const_string op, sw_uint32 oplen, sw_bool reply_expected) { sw_uint32 request_id; sw_result err; /* * reset my pointers */ self->m_send_buffer->m_bptr = self->m_send_buffer->m_base; self->m_send_buffer->m_eptr = self->m_send_buffer->m_base; /* blop out the message header */ err = sw_corby_channel_message_header(self, SW_SWOP_REQUEST); sw_check_okay(err, exit); /* service context */ err = sw_corby_buffer_put_uint32(self->m_send_buffer, 0); sw_check_okay(err, exit); /* request id */ request_id = sw_corby_channel_request_id(); err = sw_corby_buffer_put_uint32(self->m_send_buffer, request_id); sw_check_okay(err, exit); /* reply expected */ err = sw_corby_buffer_put_uint8(self->m_send_buffer, reply_expected); sw_check_okay(err, exit); /* object key */ err = sw_corby_buffer_put_sized_octets(self->m_send_buffer, (sw_const_octets) profile->m_oid, profile->m_oid_len); sw_check_okay(err, exit); /* operation */ err = sw_corby_buffer_put_sized_octets(self->m_send_buffer, (sw_octets) op, oplen); sw_check_okay(err, exit); /* principal */ err = sw_corby_buffer_put_uint32(self->m_send_buffer, 0); sw_check_okay(err, exit); *buffer = self->m_send_buffer; exit: if (err != SW_OKAY) { *buffer = NULL; } return err; }
sw_result sw_corby_channel_init_with_profile( sw_corby_channel * self, struct _sw_corby_orb * orb, sw_const_corby_profile profile, sw_socket_options options, sw_size_t bufsize) { sw_corby_channel channel; sw_socket socket; sw_result err; /* * initialize */ socket = NULL; *self = NULL; err = SW_OKAY; /* * let's try and see if we already have a connection to this guy */ for (channel = orb->m_channel_cache; channel; channel = channel->m_nextc) { if ((channel->m_to_tag == profile->m_tag) && sw_ipv4_address_equals(channel->m_to, profile->m_address) && (channel->m_to_port == profile->m_port)) { sw_int8 name_buf[16]; sw_debug(SW_LOG_NOTICE, "sharing connection to %s, %d\n", sw_ipv4_address_name(profile->m_address, name_buf, 16), profile->m_port); /* * found it */ channel->m_cache_refs++; channel->m_refs++; *self = channel; goto exit; } } /* * couldn't find it, so make a new one */ switch (profile->m_tag) { case SW_TAG_INTERNET_IOP: err = sw_tcp_socket_init(&socket); sw_check_okay(err, exit); break; case SW_TAG_UIOP: err = sw_udp_socket_init(&socket); sw_check_okay(err, exit); err = sw_socket_bind(socket, sw_ipv4_address_any(), 0); sw_check_okay(err, exit); break; case SW_TAG_MIOP: err = sw_multicast_socket_init(&socket); sw_check_okay(err, exit); err = sw_socket_bind(socket, sw_ipv4_address_any(), profile->m_port); sw_check_okay(err, exit); break; default: err = SW_E_INIT; goto exit; } /* * now let's try to connect...for connectionless protocols it just stashes this info to be used later */ err = sw_socket_connect(socket, profile->m_address, profile->m_port); sw_check_okay(err, exit); err = sw_corby_channel_init(self, orb, socket, options, bufsize); sw_check_okay(err, exit); /* * if we connected okay, then add to list of extant channels */ err = sw_ipv4_address_init_from_address(&(*self)->m_to, profile->m_address); sw_check_okay(err, exit); (*self)->m_to_tag = profile->m_tag; (*self)->m_to_port = profile->m_port; (*self)->m_send_queue_head = NULL; (*self)->m_send_queue_tail = NULL; (*self)->m_nextc = g_channel_cache; (*self)->m_prevc = NULL; if (orb->m_channel_cache) { orb->m_channel_cache->m_prevc = (*self); } orb->m_channel_cache = (*self); (*self)->m_cache_refs++; exit: if (err != SW_OKAY) { if (*self != NULL) { sw_corby_channel_fina(*self); } else if (socket != NULL) { sw_socket_fina(socket); } } return err; }