예제 #1
0
void
DNSSD_API
OnResolve(DNSServiceRef sdRef, DNSServiceFlags flags,
        uint32_t interfaceIndex, DNSServiceErrorType errorCode,
        const char * fullname, const char * hosttarget, uint16_t port,
        uint16_t txtLen, const unsigned char * txtRecord, void * context)
{

    HandleScope scope;
    ServiceRef * serviceRef = static_cast<ServiceRef*>(context);
    Handle<Function> callback = serviceRef->GetCallback();
    Handle<Object> this_ = serviceRef->GetThis();

    const size_t argc(9);
    Local<Value> args[argc];
    args[0] = Local<Object>::New(serviceRef->handle_);
    args[1] = Integer::New(flags);
    args[2] = Integer::New(interfaceIndex);
    args[3] = Integer::New(errorCode);
    args[4] = String::New(fullname);
    args[5] = String::New(hosttarget);
    args[6] = Integer::New( ntohs(port) );
    Buffer * buffer = Buffer::New(txtLen);
    memcpy(Buffer::Data(buffer->handle_), txtRecord, txtLen);
    args[7] = Local<Value>::New(buffer->handle_);
    if (serviceRef->GetContext().IsEmpty()) {
        args[8] = Local<Value>::New(Undefined());
    } else {
        args[8] = Local<Value>::New(serviceRef->GetContext());
    }
    callback->Call(this_, argc, args);
}
void
OnEnumeration(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
        DNSServiceErrorType errorCode, const char * replyDomain, void * context)
{
    if ( ! context) return;

    HandleScope scope;
    ServiceRef * serviceRef = static_cast<ServiceRef*>(context);
    Handle<Function> callback = serviceRef->GetCallback();
    Handle<Object> this_ = serviceRef->GetThis();

    const size_t argc(6);
    Local<Value> args[argc];
    args[0] = Local<Object>::New(serviceRef->handle_);
    args[1] = Integer::New(flags);
    args[2] = Integer::New(interfaceIndex);
    args[3] = Integer::New(errorCode);
    args[4] = String::New(replyDomain);
    if (serviceRef->GetContext().IsEmpty()) {
        args[5] = Local<Value>::New(Null());
    } else {
        args[5] = Local<Value>::New(serviceRef->GetContext());
    }
    callback->Call(this_, argc, args);
}
예제 #3
0
static
void
DNSSD_API
OnServiceChanged(DNSServiceRef sdRef, DNSServiceFlags flags, 
        uint32_t interfaceIndex, DNSServiceErrorType errorCode, 
        const char * serviceName, const char * serviceType,
        const char * replyDomain, void * context)
{
    NanScope();
    ServiceRef * serviceRef = static_cast<ServiceRef*>(context);
    Handle<Function> callback = serviceRef->GetCallback();
    Handle<Object> this_ = serviceRef->GetThis();

    const size_t argc(8);
    Local<Value> args[argc];
    args[0] = NanObjectWrapHandle(serviceRef);
    args[1] = NanNew<Integer>(flags);
    args[2] = NanNew<Uint32>(interfaceIndex);
    args[3] = NanNew<Integer>(errorCode);
    args[4] = stringOrUndefined(serviceName);
    args[5] = stringOrUndefined(serviceType);
    args[6] = stringOrUndefined(replyDomain);
    if (serviceRef->GetContext().IsEmpty()) {
        args[7] = NanUndefined();
    } else {
        args[7] = NanNew<Value>(serviceRef->GetContext());
    }
    NanMakeCallback(this_, callback, argc, args);
}
static
void
DNSSD_API
OnServiceRegistered(DNSServiceRef sdRef, DNSServiceFlags flags,
                    DNSServiceErrorType errorCode, const char * name,
                    const char * serviceType, const char * domain, void * context)
{
    if ( ! context) return;

    HandleScope scope;
    ServiceRef * serviceRef = static_cast<ServiceRef*>(context);
    Handle<Function> callback = serviceRef->GetCallback();
    Handle<Object> this_ = serviceRef->GetThis();

    if ( ! callback.IsEmpty() && ! this_.IsEmpty()) {
        const size_t argc(7);
        Local<Value> args[argc];
        args[0] = Local<Object>::New(serviceRef->handle_);
        args[1] = Integer::New(flags);
        args[2] = Integer::New(errorCode);
        args[3] = stringOrUndefined(name);
        args[4] = stringOrUndefined(serviceType);
        args[5] = stringOrUndefined(domain);
        if (serviceRef->GetContext().IsEmpty()) {
            args[6] = Local<Value>::New(Undefined());
        } else {
            args[6] = Local<Value>::New(serviceRef->GetContext());
        }
        callback->Call(this_, argc, args);
    }
}
예제 #5
0
void
DNSSD_API
OnResolve(DNSServiceRef sdRef, DNSServiceFlags flags,
        uint32_t interfaceIndex, DNSServiceErrorType errorCode,
        const char * fullname, const char * hosttarget, uint16_t port,
        uint16_t txtLen, const unsigned char * txtRecord, void * context)
{

    NanScope();
    ServiceRef * serviceRef = static_cast<ServiceRef*>(context);
    Handle<Function> callback = serviceRef->GetCallback();
    Handle<Object> this_ = serviceRef->GetThis();

    const size_t argc(9);
    Local<Value> args[argc];
    args[0] = NanObjectWrapHandle(serviceRef);
    args[1] = NanNew<Integer>(flags);
    args[2] = NanNew<Uint32>(interfaceIndex);
    args[3] = NanNew<Integer>(errorCode);
    args[4] = stringOrUndefined(fullname);
    args[5] = stringOrUndefined(hosttarget);
    args[6] = NanNew<Integer>( ntohs(port) );
    Local<Object> buffer = NanNewBufferHandle(txtLen);
    memcpy(Buffer::Data(buffer), txtRecord, txtLen);
    args[7] = buffer;
    if (serviceRef->GetContext().IsEmpty()) {
        args[8] = NanUndefined();
    } else {
        args[8] = NanNew<Value>(serviceRef->GetContext());
    }
    NanMakeCallback(this_, callback, argc, args);
}
예제 #6
0
static
void
DNSSD_API
OnServiceRegistered(DNSServiceRef sdRef, DNSServiceFlags flags,
        DNSServiceErrorType errorCode, const char * name,
        const char * serviceType, const char * domain, void * context)
{
    if ( ! context) return;

    NanScope();
    ServiceRef * serviceRef = static_cast<ServiceRef*>(context);
    Handle<Function> callback = serviceRef->GetCallback();
    Handle<Object> this_ = serviceRef->GetThis();

    if ( ! callback.IsEmpty() && ! this_.IsEmpty()) {
        const size_t argc(7);
        Local<Value> args[argc];
        args[0] = NanObjectWrapHandle(serviceRef);
        args[1] = NanNew<Integer>(flags);
        args[2] = NanNew<Integer>(errorCode);
        args[3] = stringOrUndefined(name);
        args[4] = stringOrUndefined(serviceType);
        args[5] = stringOrUndefined(domain);
        if (serviceRef->GetContext().IsEmpty()) {
            args[6] = NanUndefined();
        } else {
            args[6] = NanNew<Value>(serviceRef->GetContext());
        }
        NanMakeCallback(this_, callback, argc, args);
    }
}
예제 #7
0
Handle<Value>
ServiceRef::New(const Arguments & args) {
    HandleScope scope;
    if (argumentCountMismatch(args, 0)) {
        return throwArgumentCountMismatchException(args, 0);
    }
    ServiceRef * o = new ServiceRef();
    o->Wrap(args.Holder());
    return args.This();
}
void
OnAddressInfo(DNSServiceRef sdRef, DNSServiceFlags flags, 
        uint32_t interfaceIndex, DNSServiceErrorType errorCode,
        const char * hostname, const struct sockaddr * address,
        uint32_t ttl, void * context)
{
    if ( ! context) return;

    HandleScope scope;
    ServiceRef * serviceRef = static_cast<ServiceRef*>(context);
    Handle<Function> callback = serviceRef->GetCallback();
    Handle<Object> this_ = serviceRef->GetThis();

    const size_t argc(8);
    Local<Value> args[argc];
    args[0] = Local<Object>::New(serviceRef->handle_);
    args[1] = Integer::New(flags);
    args[2] = Integer::New(interfaceIndex);
    args[3] = Integer::New(errorCode);
    args[4] = String::New(hostname);
    args[5] = String::Empty();
    char ip[INET6_ADDRSTRLEN];
    struct sockaddr_in *a4;
    struct sockaddr_in6 *a6;
    switch (address->sa_family) {
        case AF_INET6:
            a6 = (struct sockaddr_in6*)(address);
            inet_ntop(AF_INET6, &(a6->sin6_addr), ip, INET6_ADDRSTRLEN);
            args[5] = String::New(ip);
            break;
        case AF_INET:
            a4 = (struct sockaddr_in*)(address);
            inet_ntop(AF_INET, &(a4->sin_addr), ip, INET6_ADDRSTRLEN);
            args[5] = String::New(ip);
            break;
        default:
            break;
    }

    args[6] = Integer::New(ttl);

    if (serviceRef->GetContext().IsEmpty()) {
        args[7] = Local<Value>::New(Null());
    } else {
        args[7] = Local<Value>::New(serviceRef->GetContext());
    }
    callback->Call(this_, argc, args);
}
Handle<Value>
DNSServiceProcessResult(Arguments const& args) {
    HandleScope scope;
    if (argumentCountMismatch(args, 1)) {
        return throwArgumentCountMismatchException(args, 1);
    }
    if ( ! args[0]->IsObject()) {
        return throwTypeError("argument 1 must be a DNSServiceRef object");
    }

    ServiceRef * ref = ObjectWrap::Unwrap<ServiceRef>(args[0]->ToObject());
    ref->SetThis(args.This());
    DNSServiceErrorType error = DNSServiceProcessResult(ref->GetServiceRef());
    if (error != kDNSServiceErr_NoError) {
        return throwMdnsError("DNSServiceProcessResult()", error);
    }
    return Undefined();
}
Handle<Value>
dnsServiceRefDeallocate(Arguments const& args) {
    HandleScope scope;
    if (argumentCountMismatch(args, 1)) {
        return throwArgumentCountMismatchException(args, 1);
    }
    if ( ! args[0]->IsObject() || ! ServiceRef::HasInstance(args[0]->ToObject())) {
        return throwTypeError("argument 1 must be a DNSServiceRef object");
    }

    ServiceRef * ref = ObjectWrap::Unwrap<ServiceRef>(args[0]->ToObject());
    if ( ! ref->IsInitialized()) {
        return throwError("DNSServiceRef is not initialized");
    }
    DNSServiceRefDeallocate( ref->GetServiceRef());
    ref->SetServiceRef(NULL);

    return Undefined();
}
void
DNSSD_API
OnEnumeration(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
        DNSServiceErrorType errorCode, const char * replyDomain, void * context)
{
    Nan::HandleScope scope;
    ServiceRef * serviceRef = static_cast<ServiceRef*>(context);
    Handle<Function> callback = serviceRef->GetCallback();
    Handle<Object> this_ = serviceRef->GetThis();

    const size_t argc(6);
    Local<Value> args[argc];
    args[0] = NanObjectWrapHandle(serviceRef);
    args[1] = NanNew<Integer>(flags);
    args[2] = NanNew<Uint32>(interfaceIndex);
    args[3] = NanNew<Integer>(errorCode);
    args[4] = stringOrUndefined(replyDomain);
    args[5] = NanNew<Value>(serviceRef->GetContext());
    NanMakeCallback(this_, callback, argc, args);
}
Handle<Value>
dnsServiceGetAddrInfo(Arguments const& args) {
    HandleScope scope;

    if (argumentCountMismatch(args, 7)) {
        return throwArgumentCountMismatchException(args, 7);
    }

    if ( ! ServiceRef::HasInstance(args[0])) {
        return throwTypeError("argument 1 must be a DNSServiceRef (sdRef)");
    }
    ServiceRef * serviceRef = ObjectWrap::Unwrap<ServiceRef>(args[0]->ToObject());
    if (serviceRef->IsInitialized()) {
        return throwError("DNSServiceRef is already initialized");
    }

    if ( ! args[1]->IsInt32()) {
        return throwError("argument 2 must be an integer (DNSServiceFlags)");
    }
    DNSServiceFlags flags = args[1]->ToInteger()->Int32Value();

    if ( ! args[2]->IsInt32()) {
        return throwTypeError("argument 3 must be an integer (interfaceIndex)");
    }
    uint32_t interfaceIndex = args[2]->ToInteger()->Int32Value();

    if ( ! args[3]->IsInt32()) {
        return throwTypeError("argument 4 must be an integer (DNSServiceProtocol)");
    }
    uint32_t protocol = args[3]->ToInteger()->Int32Value();

    if ( ! args[4]->IsString()) {
        return throwTypeError("argument 5 must be a string (hostname)");
    }
    String::Utf8Value hostname(args[4]->ToString());

    if ( ! args[5]->IsFunction()) {
        return throwTypeError("argument 6 must be a function (callBack)");
    }
    serviceRef->SetCallback(Local<Function>::Cast(args[5]));

    if ( ! args[6]->IsNull() && ! args[6]->IsUndefined()) {
        serviceRef->SetContext(args[6]);
    }

    DNSServiceErrorType error = DNSServiceGetAddrInfo( & serviceRef->GetServiceRef(),
            flags, interfaceIndex, protocol, *hostname, OnAddressInfo, serviceRef);

    if (error != kDNSServiceErr_NoError) {
        return throwMdnsError("dnsServiceGetAddrInfo()", error);
    }
    if ( ! serviceRef->SetSocketFlags()) {
        return throwError("Failed to set socket flags (O_NONBLOCK, FD_CLOEXEC)");
    }

    return Undefined();
}
Handle<Value>
DNSServiceEnumerateDomains(Arguments const& args) {
    HandleScope scope;
    if (argumentCountMismatch(args, 5)) {
        return throwArgumentCountMismatchException(args, 5);
    }
    
    if ( ! ServiceRef::HasInstance(args[0])) {
        return throwTypeError("argument 1 must be a DNSServiceRef (sdRef)");
    }
    ServiceRef * serviceRef = ObjectWrap::Unwrap<ServiceRef>(args[0]->ToObject());
    if (serviceRef->IsInitialized()) {
        return throwError("DNSServiceRef is already initialized");
    }

    if ( ! args[1]->IsInt32()) {
        return throwError("argument 2 must be an integer (DNSServiceFlags)");
    }
    DNSServiceFlags flags = args[1]->ToInteger()->Int32Value();

    if ( ! args[2]->IsInt32()) {
        return throwTypeError("argument 3 must be an integer (interfaceIndex)");
    }
    uint32_t interfaceIndex = args[2]->ToInteger()->Int32Value();

    if ( ! args[3]->IsFunction()) {
        return throwTypeError("argument 4 must be a function (callBack)");
    }
    serviceRef->SetCallback(Local<Function>::Cast(args[3]));

    serviceRef->SetContext(args[4]);

    DNSServiceErrorType error = DNSServiceEnumerateDomains( & serviceRef->GetServiceRef(),
            flags, interfaceIndex, OnEnumeration, serviceRef);

    if (error != kDNSServiceErr_NoError) {
        return throwMdnsError(error);
    }
    if ( ! serviceRef->SetSocketFlags()) {
        return throwError("Failed to set socket flags (O_NONBLOCK, FD_CLOEXEC)");
    }
    return Undefined();
}
Handle<Value>
DNSServiceRegister(Arguments const& args) {
    HandleScope scope;
    if (argumentCountMismatch(args, 11)) {
        return throwArgumentCountMismatchException(args, 11);
    }

    if ( ! ServiceRef::HasInstance(args[0])) {
        return throwTypeError("argument 1 must be a DNSServiceRef (sdRef)");
    }
    ServiceRef * serviceRef = ObjectWrap::Unwrap<ServiceRef>(args[0]->ToObject());
    if (serviceRef->IsInitialized()) {
        return throwError("DNSServiceRef is already initialized");
    }

    if ( ! args[1]->IsInt32()) {
        return throwError("argument 2 must be an integer (DNSServiceFlags)");
    }
    DNSServiceFlags flags = args[1]->ToInteger()->Int32Value();

    if ( ! args[2]->IsInt32()) {
        return throwTypeError("argument 3 must be an integer (interfaceIndex)");
    }
    uint32_t interfaceIndex = args[2]->ToInteger()->Int32Value();

    bool has_name = false;
    if ( ! args[3]->IsNull() && ! args[3]->IsUndefined()) {
        if ( ! args[3]->IsString()) {
            return throwTypeError("argument 4 must be a string (name)");
        }
        has_name = true;
    }
    String::Utf8Value name(args[3]);

    if ( ! args[4]->IsString()) {
        return throwTypeError("argument 5 must be a string (service type)");
    }
    String::Utf8Value serviceType(args[4]->ToString());

    bool has_domain = false;
    if ( ! args[5]->IsNull() && ! args[5]->IsUndefined()) {
        if ( ! args[5]->IsString()) {
            return throwTypeError("argument 6 must be a string (domain)");
        }
        has_domain = true;
    }
    String::Utf8Value domain(args[5]);

    bool has_host = false;
    if ( ! args[6]->IsNull() && ! args[6]->IsUndefined()) {
        if ( ! args[6]->IsString()) {
            return throwTypeError("argument 7 must be a string (host)");
        }
        has_host = true;
    }
    String::Utf8Value host(args[6]);

    if ( ! args[7]->IsInt32()) {
        return throwTypeError("argument 8 must be an integer (port)");
    }
    int raw_port = args[7]->ToInteger()->Int32Value();
    if (raw_port > std::numeric_limits<uint16_t>::max() || raw_port < 0) {
        return throwError("argument 8: port number is out of bounds.");
    }
    uint16_t port = static_cast<uint16_t>(raw_port);

    uint16_t txtLen(0);
    const void * txtRecord(NULL);
    if ( ! args[8]->IsNull() && ! args[8]->IsUndefined()) {
        if (Buffer::HasInstance(args[8])) {
            Local<Object> bufferObject = args[8]->ToObject();
            txtRecord = Buffer::Data(bufferObject);
            txtLen = Buffer::Length(bufferObject);
        } else if (TxtRecordRef::HasInstance(args[8])) {
            TxtRecordRef * ref = ObjectWrap::Unwrap<TxtRecordRef>(args[8]->ToObject());
            txtLen = TXTRecordGetLength( & ref->GetTxtRecordRef());
            txtRecord = TXTRecordGetBytesPtr( & ref->GetTxtRecordRef());
        } else {
            return throwTypeError("argument 9 must be a buffer or a dns_sd.TXTRecordRef");
        }
    }

    if ( ! args[9]->IsNull() && ! args[9]->IsUndefined()) {
        if ( ! args[9]->IsFunction()) {
            return throwTypeError("argument 10 must be a function (callBack)");
        }
        serviceRef->SetCallback(Local<Function>::Cast(args[9]));
    }

    if ( ! args[10]->IsNull() && ! args[10]->IsUndefined()) {
        serviceRef->SetContext(args[10]);
    }

    // eleven arguments ... srsly?
    DNSServiceErrorType error = DNSServiceRegister(
                                    & serviceRef->GetServiceRef(),
                                    flags,
                                    interfaceIndex,
                                    has_name ? * name : NULL,
                                    *serviceType,
                                    has_domain ? * domain : NULL,
                                    has_host ? * host : NULL,
                                    htons(port),
                                    txtLen,
                                    txtRecord,
                                    args[9]->IsFunction() ? OnServiceRegistered : NULL,
                                    serviceRef);
    if (error != kDNSServiceErr_NoError) {
        return throwMdnsError("DNSServiceRegister()", error);
    }
    if ( ! serviceRef->SetSocketFlags()) {
        return throwError("Failed to set socket flags (O_NONBLOCK, FD_CLOEXEC)");
    }
    return Undefined();
}
Handle<Value>
dnsServiceRegister(Arguments const& args) {
    HandleScope scope;
    if (argumentCountMismatch(args, 11)) {
        return throwArgumentCountMismatchException(args, 11);
    }

    if ( ! ServiceRef::HasInstance(args[0])) {
        return throwTypeError("argument 1 must be a DNSServiceRef (sdRef)");
    }
    ServiceRef * serviceRef = ObjectWrap::Unwrap<ServiceRef>(args[0]->ToObject());
    if (serviceRef->IsInitialized()) {
        return throwError("DNSServiceRef is already initialized");
    }

    if ( ! args[1]->IsInt32()) {
        return throwError("argument 2 must be an integer (DNSServiceFlags)");
    }
    DNSServiceFlags flags = args[1]->ToInteger()->Int32Value();

    if ( ! args[2]->IsInt32()) {
        return throwTypeError("argument 3 must be an integer (interfaceIndex)");
    }
    uint32_t interfaceIndex = args[2]->ToInteger()->Int32Value();

    bool has_name = false;
    if ( ! args[3]->IsNull() && ! args[3]->IsUndefined()) {
        if ( ! args[3]->IsString()) {
            return throwTypeError("argument 4 must be a string (name)");
        }
        has_name = true;
    }
    String::Utf8Value name(args[3]);

    if ( ! args[4]->IsString()) {
        return throwTypeError("argument 5 must be a string (regtype)");
    }
    String::Utf8Value regtype(args[4]->ToString());

    bool has_domain = false;
    if ( ! args[5]->IsNull() && ! args[5]->IsUndefined()) {
        if ( ! args[5]->IsString()) {
            return throwTypeError("argument 6 must be a string (domain)");
        }
        has_domain = true;
    }
    String::Utf8Value domain(args[5]);

    bool has_host = false;
    if ( ! args[6]->IsNull() && ! args[6]->IsUndefined()) {
        if ( ! args[6]->IsString()) {
            return throwTypeError("argument 7 must be a string (host)");
        }
        has_host = true;
    }
    String::Utf8Value host(args[6]);

    if ( ! args[7]->IsInt32()) {
        return throwTypeError("argument 8 must be an integer (port)");
    }
    int raw_port = args[7]->ToInteger()->Int32Value();
    if (raw_port > std::numeric_limits<uint16_t>::max() || raw_port < 0) {
        return throwError("argument 8: port number is out of bounds.");
    }
    uint16_t port = static_cast<uint16_t>(raw_port);

    scopedTXTRecord record;
    if (! args[8]->IsNull() && ! args[8]->IsUndefined()) {
        if (args[8]->IsObject()) {
            record.initialize();
            Local<Object> object = args[8]->ToObject();
            if (! createTXTRecord(record, object)) {
                return throwTypeError("argument 9 is not a valid TXT Record");
            }
        } else {
            return throwTypeError("argument 9 must be an object (txtRecord)");
        }
    }

    if ( ! args[9]->IsNull() && ! args[9]->IsUndefined()) {
        if ( ! args[9]->IsFunction()) {
            return throwTypeError("argument 10 must be a function (callBack)");
        }
        serviceRef->SetCallback(Local<Function>::Cast(args[9]));
    }

    if ( ! args[10]->IsNull() && ! args[10]->IsUndefined()) {
        serviceRef->SetContext(args[10]);
    }

    DNSServiceErrorType error = DNSServiceRegister(
            & serviceRef->GetServiceRef(),
            flags,
            interfaceIndex,
            has_name ? * name : NULL,
            *regtype,
            has_domain ? * domain : NULL,
            has_host ? * host : NULL,
            htons(port),
            record.getSize(),
            record.getTXTRecord(),
            OnServiceRegistered,
            serviceRef);
    if (error != kDNSServiceErr_NoError) {
        return throwMdnsError("dnsServiceRegister()", error);
    }
    if ( ! serviceRef->SetSocketFlags()) {
        return throwError("Failed to set socket flags (O_NONBLOCK, FD_CLOEXEC)");
    }
    return Undefined();
}