• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Why is Leopard annoying my users?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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 08:52:01 -0700

Alastair Houghton <mailto:email@hidden> wrote (Tuesday, November 20, 2007 6:48 AM -0000):
Well regardless of whether or not you think your application isn't
creating any TCP sockets, it clearly is; protocol 6 is TCP and the
reason you're being pestered is that your programs are binding ports
for listening on any address.

Exactly. Since I spend days trying to figure out how to create an interprocess Distributed Objects communications pipe that did *not* use TCP I'm feeling cheated.


Perhaps it's your DO set-up that needs altering here?  Maybe posting
the code will help someone spot why it's trying to bind TCP sockets?

... and ...

Nir Soffer <mailto:email@hidden> wrote (Tuesday, November 20, 2007 6:51 AM +0200):
Seems that your socket listen to to any interface on port 49287 and
49288, while you really want to listen only to localhost. I guess that
you need to configure the socket when you create the NSConnection.

But there's the rub: I spent a lot of work and time explicitly NOT creating a TCP socket.


OK, here's the meat of the code that I use to create the server's distributed objects communications port using named sockets:

NSPort* pipe = [[[NSSocketPort alloc] initWithProtocolFamily:AF_UNIX
socketType:SOCK_STREAM
protocol:0
address:[self socketAddressData]]
NSConnection* connection = [NSConnection connectionWithReceivePort:port sendPort:nil];


And before anyone suggests using Mach ports, Mach ports won't work. These sockets are created so that client processes can communicate with a launchd daemon. Leopard Mach kernel namespace changes have made this impossible to do this using Mach ports. 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.

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

_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Follow-Ups:
    • Re: Why is Leopard annoying my users?
      • From: Alastair Houghton <email@hidden>
References: 
 >Re: Why is Leopard annoying my users? (From: Alastair Houghton <email@hidden>)

  • Prev by Date: [NSTableView] option + click change of behavior between Tiger and Leopard
  • Next by Date: Re: Why is Leopard annoying my users?
  • Previous by thread: Re: Why is Leopard annoying my users?
  • Next by thread: Re: Why is Leopard annoying my users?
  • Index(es):
    • Date
    • Thread