Re: Why is Leopard annoying my users?
Re: Why is Leopard annoying my users?
- Subject: Re: Why is Leopard annoying my users?
- From: James Bucanek <email@hidden>
- Date: Tue, 20 Nov 2007 09:08:54 -0700
Hi Quinn!
Quinn <mailto:email@hidden> wrote (Tuesday, November 20,
2007 3:07 AM -0000):
What exactly are "named BSD sockets for distributed objects
communications",
A DOCommunication created from an NSSocketPort created using an
AF_UNIX domain socket file.
and how do you create them?
NSPort* pipe = [[[NSSocketPort alloc] initWithProtocolFamily:AF_UNIX
socketType:SOCK_STREAM
protocol:0
address:[self socketAddressData]]
NSConnection* connection = [NSConnection
connectionWithReceivePort:port sendPort:nil];
Are you using DO between
two different machines, or between two processes on the same machine?
This is strictly between processes on the same machine.
Specifically, this is between a daemon process (or one of its
children) and a client GUI application.
This communications was originally using Mach ports (the default
for Distributed Objects), but Leopard namespace changes now
makes this impossible. The recommended solution, according to
technote 2083
<http://developer.apple.com/technotes/tn2005/tn2083.html> is to
use UNIX Domain Sockets. I do not want to use TCP sockets for a
variety of security and performance reasons.
The firewall thinks you're listening on IP address 0.0.0.0. That IP
address means that you'll accept connections from anywhere. If your
intention was to only communicate between two processes on the same
machine, you should be listening on the loopback address (127.0.0.1).
Then something in the bowls of the Cocoa DO framework is
creating these TCP sockets.
Or, better yet, switch to UNIX domain sockets.
That's what I'm doing.
Or do your DO over Mach messages.
Not possible.
I can give you more specific advice once I know how you're setting up
your DO.
And for anyone who has other questions about the code, here's
the whole class:
//
// QRUserBSDSocketPath.m
// Quantum Recall
//
// Created by James Bucanek on 10/18/07.
// Copyright 2007 Dawn to Dusk Software. All rights reserved.
//
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#import "QRUserBSDSocketPath.h"
#import "QuantumDefs.h"
#import "QRPosixPath.h"
#if !defined(NO_LOGGER) // Compile only if the
Logger class is available
#import "FileManagerErrorLogger.h"
#import "QRException.h" // just for a property
name, not for QRException
#import "Logger.h"
#endif
@implementation QRUserBSDSocketPath
+ (QRUserBSDSocketPath*)schedulerSocketPath
{
return ([[[QRUserBSDSocketPath alloc]
initWithName:kSchedulerConnectionName] autorelease]);
}
+ (QRUserBSDSocketPath*)helperSocketPath
{
// Create a unique helper process socket name
QRUserBSDSocketPath* path;
do {
NSString* name = [NSString
stringWithFormat:kHelperConnectionName @".%x",random()&0x3fffffff];
path = [[[QRUserBSDSocketPath alloc] initWithName:name] autorelease];
} while ([path socketExists]);
return (path);
}
- (id)initWithName:(NSString*)name
{
NSString* perUserFolder = [NSString stringWithFormat:@"QRecall.%d",getuid()];
NSDictionary* createAttributes = [NSDictionary
dictionaryWithObject:[NSNumber numberWithUnsignedLong:0700] // rwx------
forKey:NSFilePosixPermissions];
if ( (self=[super initWithName:perUserFolder
inPath:[QRPosixPath varTmpPath]
withAttributes:createAttributes])!=nil )
{
socketName = [name retain];
[self create]; // the
socket's parent directory must always exist
}
return self;
}
- (void)dealloc
{
[socketName release];
[super dealloc];
}
#pragma mark Properties
- (NSString*)name
{
return (socketName);
}
- (NSString*)socketPath
{
return ([[self path] stringByAppendingPathComponent:socketName]);
}
- (NSData*)socketAddressData
{
// Create an BSD address structure that specifies the named
socket in the file system
struct sockaddr_un socketAddress;
bzero(&socketAddress,sizeof(socketAddress));
socketAddress.sun_len = sizeof(socketAddress);
socketAddress.sun_family = AF_UNIX;
strcpy(socketAddress.sun_path,[[self socketPath] cStringUsingEncoding:NSASCIIStringEncoding]);
// socketAddress.sun_len = SUN_LEN(&socketAddress);
NSData* socketAddressData = [NSData dataWithBytes:&socketAddress
length:/*SUN_LEN(&socketAddress)*/sizeof(socketAddress)];
return (socketAddressData);
}
#pragma mark Socket Utilities
- (BOOL)socketExists
{
return ([[NSFileManager defaultManager]
fileExistsAtPath:[self socketPath]]);
}
- (void)deleteSocket
{
#ifdef NO_LOGGER
[[NSFileManager defaultManager] removeFileAtPath:[self
socketPath] handler:nil];
#else
if (![[NSFileManager defaultManager] removeFileAtPath:[self
socketPath] handler:[FileManagerErrorLogger errorLogger]])
{
LogLineIdentifier* lID = [Logger log:kLogError
message:@"Unable to delete communications pipe"];
[Logger log:kLogDetails inLine:lID key:kDetailsPath
value:[self socketPath]];
}
else
{
[Logger log:kLogDebug format:@"%s %@",__func__,[self socketPath]];
}
#endif
}
#pragma mark Notifications
- (void)portDidBecomeInvalidNotification:(NSNotification*)notification
{
#pragma unused(notification)
#if !defined(NO_LOGGER)
[Logger log:kLogDebug format:@"%s",__func__];
#endif
// The port that uses this BSD socket is no longer valid.
// Delete the underlying pipe file.
[self deleteSocket];
[self autorelease]; // balance retain in
-[QRUserBSDSocketPath createPort]
}
#pragma mark Communication ports
- (NSConnection*)serverConnection
{
NSConnection* connection = nil;
NSPort* port = [self createPort];
if (port!=nil)
connection = [NSConnection
connectionWithReceivePort:port sendPort:nil];
return (connection);
}
- (NSConnection*)clientConnection
{
NSConnection* connection = nil;
NSPort* port = nil;
if ([self socketExists])
port = [self connectPort];
if (port!=nil)
connection = [NSConnection
connectionWithReceivePort:nil sendPort:port];
return (connection);
}
- (NSPort*)createPort
{
// This method creates the pipe file, binds to it, and
returns it as an NSPort object.
// It fails if the pipe file already exists.
NSPort* pipe = [[[NSSocketPort alloc] initWithProtocolFamily:AF_UNIX
socketType:SOCK_STREAM
protocol:0
address:[self socketAddressData]] autorelease];
if (pipe!=nil)
{
// Creating this NSSocketPort will bind() the address,
which creates a pipe file.
// Listen for the NSPortDidBecomeInvalidNotification
notification and delete the pipe file
// when it's no longer being used.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(portDidBecomeInvalidNotification:)
name:NSPortDidBecomeInvalidNotification
object:pipe];
[self retain]; // retain until the
notification is received
#if !defined(NO_LOGGER)
[Logger log:kLogDebug format:@"%s %@",__func__,[self socketPath]];
}
else
{
[Logger log:kLogDebug format:@"%s failed to create
%@",__func__,[self socketPath]];
#endif
}
return (pipe);
}
- (NSPort*)connectPort
{
// This method connects with an already existing socket in
the file system.
// It fails (returns nil) if the socket does not exist.
NSPort* pipe = nil;
if ([self socketExists])
pipe = [[[NSSocketPort alloc] initRemoteWithProtocolFamily:AF_UNIX
socketType:SOCK_STREAM
protocol:0
address:[self socketAddressData]] autorelease];
#if !defined(NO_LOGGER)
if (pipe!=nil)
[Logger log:kLogDebug format:@"%s %@",__func__,[self socketPath]];
else
[Logger log:kLogDebug format:@"%s failed to connect
%@",__func__,[self socketPath]];
#endif
return (pipe);
}
@end
--
James Bucanek
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden