static PRFileDesc *PushNewLayers(PRFileDesc *stack) { PRDescIdentity tmp_identity; PRFileDesc *layer; PRStatus rv; /* push a dummy layer */ tmp_identity = PR_GetUniqueIdentity("Dummy 1"); layer = PR_CreateIOLayerStub(tmp_identity, PR_GetDefaultIOMethods()); rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); if (verbosity > quiet) PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack); PR_ASSERT(PR_SUCCESS == rv); /* push a data procesing layer */ layer = PR_CreateIOLayerStub(identity, &myMethods); rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); if (verbosity > quiet) PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack); PR_ASSERT(PR_SUCCESS == rv); /* push another dummy layer */ tmp_identity = PR_GetUniqueIdentity("Dummy 2"); layer = PR_CreateIOLayerStub(tmp_identity, PR_GetDefaultIOMethods()); rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); if (verbosity > quiet) PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack); PR_ASSERT(PR_SUCCESS == rv); return stack; } /* PushLayer */
static void Initialize() { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); static bool initialized = false; if (initialized) { return; } nsNamedPipeLayerIdentity = PR_GetUniqueIdentity("Named Pipe layer"); nsNamedPipeLayerMethods = *PR_GetDefaultIOMethods(); nsNamedPipeLayerMethods.close = nsNamedPipeClose; nsNamedPipeLayerMethods.read = nsNamedPipeRead; nsNamedPipeLayerMethods.write = nsNamedPipeWrite; nsNamedPipeLayerMethods.available = nsNamedPipeAvailable; nsNamedPipeLayerMethods.available64 = nsNamedPipeAvailable64; nsNamedPipeLayerMethods.fsync = nsNamedPipeSync; nsNamedPipeLayerMethods.connect = nsNamedPipeConnect; nsNamedPipeLayerMethods.recv = nsNamedPipeRecv; nsNamedPipeLayerMethods.send = nsNamedPipeSend; nsNamedPipeLayerMethods.poll = nsNamedPipePoll; nsNamedPipeLayerMethods.getsocketoption = nsNamedPipeGetSocketOption; nsNamedPipeLayerMethods.setsocketoption = nsNamedPipeSetSocketOption; nsNamedPipeLayerMethods.connectcontinue = nsNamedPipeConnectContinue; initialized = true; }
static void ssl_nss_init_nss(void) { #if NSS_VMAJOR > 3 || ( NSS_VMAJOR == 3 && NSS_VMINOR >= 14 ) SSLVersionRange supported, enabled; #endif /* NSS >= 3.14 */ PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); NSS_NoDB_Init("."); NSS_SetDomesticPolicy(); SSL_CipherPrefSetDefault(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 1); SSL_CipherPrefSetDefault(TLS_DHE_DSS_WITH_AES_256_CBC_SHA, 1); SSL_CipherPrefSetDefault(TLS_RSA_WITH_AES_256_CBC_SHA, 1); SSL_CipherPrefSetDefault(TLS_DHE_DSS_WITH_RC4_128_SHA, 1); SSL_CipherPrefSetDefault(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 1); SSL_CipherPrefSetDefault(TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 1); SSL_CipherPrefSetDefault(SSL_RSA_WITH_RC4_128_SHA, 1); SSL_CipherPrefSetDefault(TLS_RSA_WITH_AES_128_CBC_SHA, 1); SSL_CipherPrefSetDefault(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 1); SSL_CipherPrefSetDefault(SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 1); SSL_CipherPrefSetDefault(SSL_DHE_RSA_WITH_DES_CBC_SHA, 1); SSL_CipherPrefSetDefault(SSL_DHE_DSS_WITH_DES_CBC_SHA, 1); #if NSS_VMAJOR > 3 || ( NSS_VMAJOR == 3 && NSS_VMINOR >= 14 ) /* Get the ranges of supported and enabled SSL versions */ if ((SSL_VersionRangeGetSupported(ssl_variant_stream, &supported) == SECSuccess) && (SSL_VersionRangeGetDefault(ssl_variant_stream, &enabled) == SECSuccess)) { purple_debug_info("nss", "TLS supported versions: " "0x%04hx through 0x%04hx\n", supported.min, supported.max); purple_debug_info("nss", "TLS versions allowed by default: " "0x%04hx through 0x%04hx\n", enabled.min, enabled.max); /* Make sure SSL 3.0 is disabled (it's old and everyone should be using at least TLS 1.0 by now), and make sure all versions of TLS supported by the local library are enabled (for some reason NSS doesn't enable newer versions of TLS by default -- more context in ticket #15909). */ if (enabled.min != SSL_LIBRARY_VERSION_TLS_1_0 || supported.max > enabled.max) { enabled.max = supported.max; if (SSL_VersionRangeSetDefault(ssl_variant_stream, &enabled) == SECSuccess) { purple_debug_info("nss", "Changed allowed TLS versions to " "0x%04hx through 0x%04hx\n", enabled.min, enabled.max); } else { purple_debug_error("nss", "Error setting allowed TLS versions to " "0x%04hx through 0x%04hx\n", enabled.min, enabled.max); } } } #endif /* NSS >= 3.14 */ /** Disable OCSP Checking until we can make that use our HTTP & Proxy stuff */ CERT_EnableOCSPChecking(PR_FALSE); _identity = PR_GetUniqueIdentity("Purple"); _nss_methods = PR_GetDefaultIOMethods(); }
static void LazyInitSocket() { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); if (sPollableEventLayerMethodsPtr) { return; } sPollableEventLayerIdentity = PR_GetUniqueIdentity("PollableEvent Layer"); sPollableEventLayerMethods = *PR_GetDefaultIOMethods(); sPollableEventLayerMethodsPtr = &sPollableEventLayerMethods; }
// static void ClosingService::Start() { if (!sTcpUdpPRCloseLayerMethodsPtr) { sTcpUdpPRCloseLayerId = PR_GetUniqueIdentity("TCP and UDP PRClose layer"); PR_ASSERT(PR_INVALID_IO_LAYER != sTcpUdpPRCloseLayerId); sTcpUdpPRCloseLayerMethods = *PR_GetDefaultIOMethods(); sTcpUdpPRCloseLayerMethods.close = TcpUdpPRCloseLayerClose; sTcpUdpPRCloseLayerMethodsPtr = &sTcpUdpPRCloseLayerMethods; } if (!sInstance) { ClosingService* service = new ClosingService(); if (NS_SUCCEEDED(service->StartInternal())) { NS_ADDREF(service); sInstance = service; } else { delete service; } } }
NSAPI_PUBLIC int net_init(int security_on) { _netlayer_identity = PR_GetUniqueIdentity("netlayer/" PRODUCT_FULL_VERSION_ID); const PRIOMethods *default_methods = PR_GetDefaultIOMethods(); _netlayer_methods = *default_methods; _netlayer_methods.recv = _netlayer_method_recv; _netlayer_methods.read = _netlayer_method_read; _netlayer_methods.available = _netlayer_method_available; _netlayer_methods.available64 = _netlayer_method_available64; _netlayer_methods.seek = _netlayer_method_seek; _netlayer_methods.seek64 = _netlayer_method_seek64; _netlayer_methods.recvfrom = _netlayer_method_recvfrom; _netlayer_methods.poll = _netlayer_method_poll; _netlayer_methods.acceptread = _netlayer_method_acceptread; _netlayer_methods.close = _netlayer_method_close; _netlayer_default_close_method = default_methods->close; return 0; }
PRIntn main(PRIntn argc, char **argv) { PRStatus rv; PRIntn mits; PLOptStatus os; PRFileDesc *client, *service; PRFileDesc *client_stack, *service_stack; PRNetAddr any_address; const char *server_name = NULL; const PRIOMethods *stubMethods; PRThread *client_thread, *server_thread; PRThreadScope thread_scope = PR_LOCAL_THREAD; PLOptState *opt = PL_CreateOptState(argc, argv, "dqGC:c:p:"); while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { if (PL_OPT_BAD == os) continue; switch (opt->option) { case 0: server_name = opt->value; break; case 'd': /* debug mode */ if (verbosity < noisy) verbosity = ChangeVerbosity(verbosity, 1); break; case 'q': /* debug mode */ if (verbosity > silent) verbosity = ChangeVerbosity(verbosity, -1); break; case 'G': /* use global threads */ thread_scope = PR_GLOBAL_THREAD; break; case 'C': /* number of threads waiting */ major_iterations = atoi(opt->value); break; case 'c': /* number of client threads */ minor_iterations = atoi(opt->value); break; case 'p': /* default port */ default_port = atoi(opt->value); break; default: break; } } PL_DestroyOptState(opt); PR_STDIO_INIT(); logFile = PR_GetSpecialFD(PR_StandardError); identity = PR_GetUniqueIdentity("Dummy"); stubMethods = PR_GetDefaultIOMethods(); /* ** The protocol we're going to implement is one where in order to initiate ** a send, the sender must first solicit permission. Therefore, every ** send is really a send - receive - send sequence. */ myMethods = *stubMethods; /* first get the entire batch */ myMethods.recv = MyRecv; /* then override the ones we care about */ myMethods.send = MySend; /* then override the ones we care about */ if (NULL == server_name) rv = PR_InitializeNetAddr( PR_IpAddrLoopback, default_port, &server_address); else { rv = PR_StringToNetAddr(server_name, &server_address); PR_ASSERT(PR_SUCCESS == rv); rv = PR_InitializeNetAddr( PR_IpAddrNull, default_port, &server_address); } PR_ASSERT(PR_SUCCESS == rv); /* one type w/o layering */ mits = minor_iterations; while (major_iterations-- > 0) { if (verbosity > silent) PR_fprintf(logFile, "Beginning non-layered test\n"); client = PR_NewTCPSocket(); PR_ASSERT(NULL != client); service = PR_NewTCPSocket(); PR_ASSERT(NULL != service); rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv); minor_iterations = mits; server_thread = PR_CreateThread( PR_USER_THREAD, Server, service, PR_PRIORITY_HIGH, thread_scope, PR_JOINABLE_THREAD, 16 * 1024); PR_ASSERT(NULL != server_thread); client_thread = PR_CreateThread( PR_USER_THREAD, Client, client, PR_PRIORITY_NORMAL, thread_scope, PR_JOINABLE_THREAD, 16 * 1024); PR_ASSERT(NULL != client_thread); rv = PR_JoinThread(client_thread); PR_ASSERT(PR_SUCCESS == rv); rv = PR_JoinThread(server_thread); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv); if (verbosity > silent) PR_fprintf(logFile, "Ending non-layered test\n"); /* with layering */ if (verbosity > silent) PR_fprintf(logFile, "Beginning layered test\n"); client = PR_NewTCPSocket(); PR_ASSERT(NULL != client); PushLayer(client); service = PR_NewTCPSocket(); PR_ASSERT(NULL != service); PushLayer(service); rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv); minor_iterations = mits; server_thread = PR_CreateThread( PR_USER_THREAD, Server, service, PR_PRIORITY_HIGH, thread_scope, PR_JOINABLE_THREAD, 16 * 1024); PR_ASSERT(NULL != server_thread); client_thread = PR_CreateThread( PR_USER_THREAD, Client, client, PR_PRIORITY_NORMAL, thread_scope, PR_JOINABLE_THREAD, 16 * 1024); PR_ASSERT(NULL != client_thread); rv = PR_JoinThread(client_thread); PR_ASSERT(PR_SUCCESS == rv); rv = PR_JoinThread(server_thread); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv); /* with layering, using new style stack */ if (verbosity > silent) PR_fprintf(logFile, "Beginning layered test with new style stack\n"); client = PR_NewTCPSocket(); PR_ASSERT(NULL != client); client_stack = PR_CreateIOLayer(client); PushNewLayers(client_stack); service = PR_NewTCPSocket(); PR_ASSERT(NULL != service); service_stack = PR_CreateIOLayer(service); PushNewLayers(service_stack); rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv); minor_iterations = mits; server_thread = PR_CreateThread( PR_USER_THREAD, Server, service_stack, PR_PRIORITY_HIGH, thread_scope, PR_JOINABLE_THREAD, 16 * 1024); PR_ASSERT(NULL != server_thread); client_thread = PR_CreateThread( PR_USER_THREAD, Client, client_stack, PR_PRIORITY_NORMAL, thread_scope, PR_JOINABLE_THREAD, 16 * 1024); PR_ASSERT(NULL != client_thread); rv = PR_JoinThread(client_thread); PR_ASSERT(PR_SUCCESS == rv); rv = PR_JoinThread(server_thread); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Close(client_stack); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Close(service_stack); PR_ASSERT(PR_SUCCESS == rv); if (verbosity > silent) PR_fprintf(logFile, "Ending layered test\n"); } return 0; } /* main */
int main(int argc, char **argv) { PRHostEnt he; PRStatus status; PRIntn next_index; PRUint16 port_number; char netdb_buf[PR_NETDB_BUF_SIZE]; PRNetAddr client_addr, server_addr; PRThread *client_thread, *server_thread; PRIntervalTime delta = PR_MillisecondsToInterval(500); err_out = PR_STDERR; std_out = PR_STDOUT; accept_timeout = PR_SecondsToInterval(2); emu_layer_ident = PR_GetUniqueIdentity("Emulated AcceptRead"); emu_layer_methods = *PR_GetDefaultIOMethods(); emu_layer_methods.acceptread = emu_AcceptRead; if (argc != 2 && argc != 3) port_number = DEFAULT_PORT; else port_number = (PRUint16)atoi(argv[(argc == 2) ? 1 : 2]); status = PR_InitializeNetAddr(PR_IpAddrAny, port_number, &server_addr); if (PR_SUCCESS != status) { PL_FPrintError(err_out, "PR_InitializeNetAddr failed"); PR_ProcessExit(1); } if (argc < 3) { status = PR_InitializeNetAddr( PR_IpAddrLoopback, port_number, &client_addr); if (PR_SUCCESS != status) { PL_FPrintError(err_out, "PR_InitializeNetAddr failed"); PR_ProcessExit(1); } } else { status = PR_GetHostByName( argv[1], netdb_buf, sizeof(netdb_buf), &he); if (status == PR_FAILURE) { PL_FPrintError(err_out, "PR_GetHostByName failed"); PR_ProcessExit(1); } next_index = PR_EnumerateHostEnt(0, &he, port_number, &client_addr); if (next_index == -1) { PL_FPrintError(err_out, "PR_EnumerateHostEnt failed"); PR_ProcessExit(1); } } for ( write_dally = 0; write_dally < accept_timeout + (2 * delta); write_dally += delta) { PR_fprintf( std_out, "Testing w/ write_dally = %d msec\n", PR_IntervalToMilliseconds(write_dally)); server_thread = PR_CreateThread( PR_USER_THREAD, AcceptingThread, &server_addr, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); if (server_thread == NULL) { PL_FPrintError(err_out, "PR_CreateThread (server) failed"); PR_ProcessExit(1); } PR_Sleep(delta); /* let the server pot thicken */ client_thread = PR_CreateThread( PR_USER_THREAD, ConnectingThread, &client_addr, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); if (client_thread == NULL) { PL_FPrintError(err_out, "PR_CreateThread (client) failed"); PR_ProcessExit(1); } if (PR_JoinThread(client_thread) == PR_FAILURE) PL_FPrintError(err_out, "PR_JoinThread (client) failed"); if (PR_JoinThread(server_thread) == PR_FAILURE) PL_FPrintError(err_out, "PR_JoinThread (server) failed"); } return 0; }
// add SOCKS IO layer to an existing socket nsresult nsSOCKSIOLayerAddToSocket(int32_t family, const char *host, int32_t port, const char *proxyHost, int32_t proxyPort, int32_t socksVersion, uint32_t flags, PRFileDesc *fd, nsISupports** info) { NS_ENSURE_TRUE((socksVersion == 4) || (socksVersion == 5), NS_ERROR_NOT_INITIALIZED); if (firstTime) { //XXX hack until NSPR provides an official way to detect system IPv6 // support (bug 388519) PRFileDesc *tmpfd = PR_OpenTCPSocket(PR_AF_INET6); if (!tmpfd) { ipv6Supported = false; } else { // If the system does not support IPv6, NSPR will push // IPv6-to-IPv4 emulation layer onto the native layer ipv6Supported = PR_GetIdentitiesLayer(tmpfd, PR_NSPR_IO_LAYER) == tmpfd; PR_Close(tmpfd); } nsSOCKSIOLayerIdentity = PR_GetUniqueIdentity("SOCKS layer"); nsSOCKSIOLayerMethods = *PR_GetDefaultIOMethods(); nsSOCKSIOLayerMethods.connect = nsSOCKSIOLayerConnect; nsSOCKSIOLayerMethods.connectcontinue = nsSOCKSIOLayerConnectContinue; nsSOCKSIOLayerMethods.poll = nsSOCKSIOLayerPoll; nsSOCKSIOLayerMethods.bind = nsSOCKSIOLayerBind; nsSOCKSIOLayerMethods.acceptread = nsSOCKSIOLayerAcceptRead; nsSOCKSIOLayerMethods.getsockname = nsSOCKSIOLayerGetName; nsSOCKSIOLayerMethods.getpeername = nsSOCKSIOLayerGetPeerName; nsSOCKSIOLayerMethods.accept = nsSOCKSIOLayerAccept; nsSOCKSIOLayerMethods.listen = nsSOCKSIOLayerListen; nsSOCKSIOLayerMethods.close = nsSOCKSIOLayerClose; firstTime = false; #if defined(PR_LOGGING) gSOCKSLog = PR_NewLogModule("SOCKS"); #endif } LOGDEBUG(("Entering nsSOCKSIOLayerAddToSocket().")); PRFileDesc * layer; PRStatus rv; layer = PR_CreateIOLayerStub(nsSOCKSIOLayerIdentity, &nsSOCKSIOLayerMethods); if (! layer) { LOGERROR(("PR_CreateIOLayerStub() failed.")); return NS_ERROR_FAILURE; } nsSOCKSSocketInfo * infoObject = new nsSOCKSSocketInfo(); if (!infoObject) { // clean up IOLayerStub LOGERROR(("Failed to create nsSOCKSSocketInfo().")); PR_DELETE(layer); return NS_ERROR_FAILURE; } NS_ADDREF(infoObject); infoObject->Init(socksVersion, family, proxyHost, proxyPort, host, flags); layer->secret = (PRFilePrivate*) infoObject; rv = PR_PushIOLayer(fd, PR_GetLayersIdentity(fd), layer); if (rv == PR_FAILURE) { LOGERROR(("PR_PushIOLayer() failed. rv = %x.", rv)); NS_RELEASE(infoObject); PR_DELETE(layer); return NS_ERROR_FAILURE; } *info = static_cast<nsISOCKSSocketInfo*>(infoObject); NS_ADDREF(*info); return NS_OK; }
PR_END_EXTERN_C /* ----------------------------- filter_fill ------------------------------ */ static Filter *filter_fill(const char *name, int order, const FilterMethods *methods, int flags, Filter *filter) { filter->name = PERM_STRDUP(name); filter->flags = flags; filter->order = order & FILTER_MASK; // Reserve topmost bits for future use /* * Setup NSAPI-specific filter methods */ if (methods->insert) { filter->insert = methods->insert; } else { filter->insert = &filtermethod_always_insert; } if (methods->remove) { filter->remove = methods->remove; } else { filter->remove = &filtermethod_default_remove; } if (methods->read) { filter->read = methods->read; } else { filter->read = NULL; } /* * Setup NSPR filter methods */ filter->priomethods = *PR_GetDefaultIOMethods(); filter->priomethods.file_type = PR_DESC_LAYERED; // Assert NSPR IO layer and NSAPI filter binary compatibility PR_ASSERT(sizeof(PRSendFileData) == sizeof(sendfiledata)); PR_ASSERT(sizeof(PRIOVec) == sizeof(NSAPIIOVec)); PR_ASSERT(sizeof(PRStatus) == sizeof(int)); PR_ASSERT(sizeof(PRInt32) == sizeof(int)); PR_ASSERT(sizeof(PRSize) == sizeof(size_t)); filter->priomethods.close = &filtermethod_close; if (methods->flush) { filter->priomethods.fsync = (PRFsyncFN)methods->flush; } else { filter->priomethods.fsync = &filtermethod_default_fsync; } if (methods->read) { filter->priomethods.read = &filtermethod_emulate_read; filter->priomethods.recv = &filtermethod_emulate_recv; } else { filter->priomethods.read = &filtermethod_default_read; filter->priomethods.recv = &filtermethod_default_recv; } if (methods->write) { filter->priomethods.write = (PRWriteFN)methods->write; filter->priomethods.send = (PRSendFN)methods->write; } else { filter->priomethods.write = &filtermethod_default_write; filter->priomethods.send = &filtermethod_default_send; } if (methods->writev) { filter->priomethods.writev = (PRWritevFN)methods->writev; } else if (methods->write) { ereport(LOG_VERBOSE, "Emulating writev for filter %s", filter->name); filter->priomethods.writev = &filtermethod_emulate_writev; } else { filter->priomethods.writev = &filtermethod_default_writev; } if (methods->sendfile) { filter->priomethods.sendfile = (PRSendfileFN)methods->sendfile; } else if (methods->write) { ereport(LOG_VERBOSE, "Emulating sendfile for filter %s", filter->name); filter->priomethods.sendfile = &filtermethod_emulate_sendfile; } else { filter->priomethods.sendfile = &filtermethod_default_sendfile; } /* * Add the filter to the front of the server-wide list */ PR_Lock(_filter_list_lock); filter->next = _filter_list; _filter_list = filter; _filter_hash.remove((void *)filter->name); _filter_hash.insert((void *)filter->name, filter); PR_Unlock(_filter_list_lock); return filter; }
NSAPI_PUBLIC PRStatus filter_init(void) { _filter_list_lock = PR_NewLock(); // Get an IO layer identity for active NSAPI filters _filter_identity = PR_GetUniqueIdentity("NSAPI filter"); // Figure out the NSS IO layer identity PRFileDesc *model = PR_NewTCPSocket(); if (model) { model = SSL_ImportFD(NULL, model); _filter_ssl_identity = model->identity; PR_Close(model); } // Get an IO layer identity for our "null" (bottom of stack) IO layer _filter_null_identity = PR_GetUniqueIdentity("NSAPI filter stack"); // Initialize the PRIOMethods for our "null" (bottom of stack) IO layer _filter_null_priomethods = *PR_GetDefaultIOMethods(); _filter_null_priomethods.file_type = PR_DESC_PIPE; // Not socket/file/layer _filter_null_priomethods.close = &iolayer_null_close; _filter_null_priomethods.read = &iolayer_null_read; _filter_null_priomethods.write = &iolayer_null_write; _filter_null_priomethods.available = &iolayer_null_available; _filter_null_priomethods.available64 = &iolayer_null_available64; _filter_null_priomethods.fsync = &iolayer_null_fsync; _filter_null_priomethods.seek = &iolayer_null_seek; _filter_null_priomethods.seek64 = &iolayer_null_seek64; _filter_null_priomethods.fileInfo = &iolayer_null_fileinfo; _filter_null_priomethods.fileInfo64 = &iolayer_null_fileinfo64; _filter_null_priomethods.writev = &iolayer_null_writev; _filter_null_priomethods.connect = &iolayer_null_connect; _filter_null_priomethods.accept = &iolayer_null_accept; _filter_null_priomethods.bind = &iolayer_null_bind; _filter_null_priomethods.listen = &iolayer_null_listen; _filter_null_priomethods.shutdown = &iolayer_null_shutdown; _filter_null_priomethods.recv = &iolayer_null_recv; _filter_null_priomethods.send = &iolayer_null_send; _filter_null_priomethods.recvfrom = &iolayer_null_recvfrom; _filter_null_priomethods.sendto = &iolayer_null_sendto; _filter_null_priomethods.poll = &iolayer_null_poll; _filter_null_priomethods.acceptread = &iolayer_null_acceptread; _filter_null_priomethods.transmitfile = &iolayer_null_transmitfile; _filter_null_priomethods.getsockname = &iolayer_null_getsockname; _filter_null_priomethods.getpeername = &iolayer_null_getpeername; _filter_null_priomethods.getsocketoption = &iolayer_null_getsocketoption; _filter_null_priomethods.setsocketoption = &iolayer_null_setsocketoption; _filter_null_priomethods.sendfile = &iolayer_null_sendfile; _filter_null_priomethods.connectcontinue = &iolayer_null_connectcontinue; // Initialize pseudo-filters FilterMethods pseudo_methods = FILTER_METHODS_INITIALIZER; pseudo_methods.insert = &filtermethod_never_insert; // user can't insert these filter_fill(FILTER_NAME_TOP, 0x7fffffff /* top */, &pseudo_methods, 0, &_filter_top); filter_fill(FILTER_NAME_BOTTOM, 0 /* bottom */, &pseudo_methods, 0, &_filter_bottom); filter_fill(FILTER_NAME_NETWORK, FILTER_NETWORK, &pseudo_methods, 0, &_filter_network); filter_fill(FILTER_NAME_SSL, FILTER_TRANSPORT_CODING, &pseudo_methods, 0, &_filter_ssl); // Create a filter to call into Output stage and filter_set_request() FilterMethods callback_methods = FILTER_METHODS_INITIALIZER; callback_methods.insert = &filtermethod_always_insert; callback_methods.flush = &filtermethod_callback_flush; callback_methods.read = &filtermethod_callback_read; callback_methods.write = &filtermethod_callback_write; callback_methods.writev = (FilterWritevFunc*)&filtermethod_callback_writev; callback_methods.sendfile = (FilterSendfileFunc*)&filtermethod_callback_sendfile; _filter_callback = filter_create_internal("magnus-internal/callback", FILTER_TOPMOST, &callback_methods, FILTER_CALLS_CALLBACKS); if (!_filter_callback) return PR_FAILURE; // We'll use this per-DaemonSession slot to cache unused PRFileDescs _filter_prfiledesc_slot = session_alloc_thread_slot(NULL); // Will pass this empty pblock (instead of NULL) if filter_insert() is // called with a NULL pblock * _empty_pb = pblock_create(1); return PR_SUCCESS; }
static PRStatus PR_CALLBACK MyClose(PRFileDesc *fd) { PR_DELETE(fd->secret); /* manage my secret file object */ return (PR_GetDefaultIOMethods())->close(fd); /* let him do all the work */ } /* MyClose */
NS_IMETHODIMP nsWINCESSLSocketProvider::NewSocket(PRInt32 family, const char *host, PRInt32 port, const char *proxyHost, PRInt32 proxyPort, PRUint32 flags, PRFileDesc **result, nsISupports **socksInfo) { static PRBool firstTime = PR_TRUE; if (firstTime) { nsWINCESSLIOLayerIdentity = PR_GetUniqueIdentity("WINCESSL layer"); nsWINCESSLIOLayerMethods = *PR_GetDefaultIOMethods(); nsWINCESSLIOLayerMethods.connect = nsWINCESSLIOLayerConnect; nsWINCESSLIOLayerMethods.close = nsWINCESSLIOLayerClose; nsWINCESSLIOLayerMethods.available = nsWINCESSLIOLayerAvailable; nsWINCESSLIOLayerMethods.write = nsWINCESSLIOLayerWrite; nsWINCESSLIOLayerMethods.read = nsWINCESSLIOLayerRead; nsWINCESSLIOLayerMethods.poll = nsWINCESSLIOLayerPoll; firstTime = PR_FALSE; } PRFileDesc *fd = PR_OpenTCPSocket(family); if (!fd) return NS_ERROR_OUT_OF_MEMORY; PRFileDesc * layer; PRStatus rv; layer = PR_CreateIOLayerStub(nsWINCESSLIOLayerIdentity, &nsWINCESSLIOLayerMethods); if (! layer) return NS_ERROR_UNEXPECTED; nsWINCESSLSocketInfo * infoObject = new nsWINCESSLSocketInfo(); if (!infoObject) return NS_ERROR_OUT_OF_MEMORY; NS_ADDREF(infoObject); layer->secret = (PRFilePrivate*) infoObject; rv = PR_PushIOLayer(fd, PR_GetLayersIdentity(fd), layer); if (NS_FAILED(rv)) return NS_ERROR_UNEXPECTED; nsresult initrv = infoObject->Init(host, proxyHost, proxyPort); if (NS_FAILED(initrv)) { MessageBox(0, "Can not create ssl socket.", "Can not create ssl socket.", MB_APPLMODAL | MB_TOPMOST | MB_SETFOREGROUND); return NS_ERROR_FAILURE; } *result = fd; *socksInfo = (nsISupports*) (nsITransportSecurityInfo*) infoObject; return NS_OK; }