static bool set_sockaddr(sockaddr_storage &sa_storage, Socket *sock, const char *addr, int port, struct sockaddr *&sa_ptr, size_t &sa_size) { struct sockaddr *sock_type = (struct sockaddr*) &sa_storage; switch (sock->getType()) { case AF_UNIX: { struct sockaddr_un *sa = (struct sockaddr_un *)sock_type; memset(sa, 0, sizeof(sa_storage)); sa->sun_family = AF_UNIX; snprintf(sa->sun_path, 108, "%s", addr); sa_ptr = (struct sockaddr *)sa; sa_size = SUN_LEN(sa); } break; case AF_INET: { struct sockaddr_in *sa = (struct sockaddr_in *)sock_type; memset(sa, 0, sizeof(sa_storage)); /* Apparently, Mac OSX needs this */ sa->sin_family = AF_INET; sa->sin_port = htons((unsigned short) port); if (!php_set_inet_addr(sa, addr, sock)) { return false; } sa_ptr = (struct sockaddr *)sa; sa_size = sizeof(struct sockaddr_in); } break; case AF_INET6: { struct sockaddr_in6 *sa = (struct sockaddr_in6 *)sock_type; memset(sa, 0, sizeof(sa_storage)); /* Apparently, Mac OSX needs this */ sa->sin6_family = AF_INET6; sa->sin6_port = htons((unsigned short) port); if (!php_set_inet6_addr(sa, addr, sock)) { return false; } sa_ptr = (struct sockaddr *)sa; sa_size = sizeof(struct sockaddr_in6); } break; default: raise_warning("unsupported socket type '%d', must be " "AF_UNIX, AF_INET, or AF_INET6", sock->getType()); return false; } return true; }
static void from_zval_write_sin6_addr(const zval *zaddr_str, char *addr6, ser_context *ctx) { int res; struct sockaddr_in6 saddr6 = {0}; zend_string *addr_str; addr_str = zval_get_string((zval *) zaddr_str); res = php_set_inet6_addr(&saddr6, addr_str->val, ctx->sock); if (res) { memcpy(addr6, &saddr6.sin6_addr, sizeof saddr6.sin6_addr); } else { /* error already emitted, but let's emit another more relevant */ do_from_zval_err(ctx, "could not resolve address '%s' to get an AF_INET6 " "address", Z_STRVAL_P(zaddr_str)); } zend_string_release(addr_str); }
Variant HHVM_FUNCTION(socket_sendto, const Resource& socket, const String& buf, int len, int flags, const String& addr, int port /* = -1 */) { auto sock = cast<Socket>(socket); if (len > buf.size()) { len = buf.size(); } int retval; switch (sock->getType()) { case AF_UNIX: { struct sockaddr_un s_un; memset(&s_un, 0, sizeof(s_un)); s_un.sun_family = AF_UNIX; snprintf(s_un.sun_path, 108, "%s", addr.data()); retval = sendto(sock->fd(), buf.data(), len, flags, (struct sockaddr *)&s_un, SUN_LEN(&s_un)); } break; case AF_INET: { if (port == -1) { throw_missing_arguments_nr("socket_sendto", 6, 5); return false; } struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons((unsigned short) port); if (!php_set_inet_addr(&sin, addr.c_str(), sock)) { return false; } retval = sendto(sock->fd(), buf.data(), len, flags, (struct sockaddr *)&sin, sizeof(sin)); } break; case AF_INET6: { if (port == -1) { throw_missing_arguments_nr("socket_sendto", 6, 5); return false; } struct sockaddr_in6 sin6; memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6; sin6.sin6_port = htons((unsigned short) port); if (!php_set_inet6_addr(&sin6, addr.c_str(), sock)) { return false; } retval = sendto(sock->fd(), buf.data(), len, flags, (struct sockaddr *)&sin6, sizeof(sin6)); } break; default: raise_warning("Unsupported socket type %d", sock->getType()); return false; } if (retval == -1) { SOCKET_ERROR(sock, "unable to write to socket", errno); return false; } return retval; }