@interface ITInetSocket(Private)
-(void)doConnSetupWithHost:(NSString*)host namedPort:(NSString*)namedPort;
+-(void)realDoConnection;
-(void)spinoffReadLoop;
-(void)socketReadLoop:(id)data;
@end
sockfd = fd;
delegate = [d retain];
port = 0;
- writePipe = [[ITByteStream alloc] init];
- readPipe = [[ITByteStream alloc] init];
+ writePipe = [[ITByteStream alloc] initWithDelegate:self];
+ readPipe = [[ITByteStream alloc] initWithDelegate:d];
ai = nil;
sarr = nil;
bufs = 512;
sockfd = -1;
delegate = [d retain];
port = 0;
- writePipe = [[ITByteStream alloc] init];
- readPipe = [[ITByteStream alloc] init];
+ writePipe = [[ITByteStream alloc] initWithDelegate:self];
+ readPipe = [[ITByteStream alloc] initWithDelegate:d];
ai = nil;
sarr = nil;
bufs = 512;
-(void)disconnect
{
+ NSLog(@"Got a disconnect");
+ dieflag = 1;
+ do {} while (dieflag == 1);
}
-(void)retryConnection
{
+ ai_cur = ai_cur->ai_next?ai_cur->ai_next:ai_cur;
+ [self disconnect];
+ [self realDoConnection];
}
-(ITInetSocketState)state
{
bufs = _bufs;
}
+
+-(void)newDataAdded:(ITByteStream*)sender
+{
+ NSLog(@"writePipe got something");
+ actionflag = 1;
+ NSLog(@"thread saw actionFlag");
+}
@end
@implementation ITInetSocket(Debugging)
-(NSString*)dumpv6Addrinfo:(struct addrinfo *)_ai
{
const char *cfmt =
- "\{\n"
+ "{\n"
"Flags = %x\n"
"Family = %x\n"
"Socktype = %x\n"
"Protocol = %x\n"
"Canonname = %s\n"
"Sockaddr = \n"
- "{\n"
+ "\t{\n"
"\tLength = %x\n"
"\tFamily = %x\n"
"\tPort = %d\n"
"\tFlowinfo = %x\n"
"\tAddr = {%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx}\n"
"\tScope = %x\n"
- "}\n"
- "Next = ";
+ "\t}\n"
+ "Next = %@\n"
+ "}\n";
NSString *nsfmt = [NSString stringWithCString:cfmt];
- NSMutableString *buf = [[[NSMutableString alloc] init] autorelease];
+ struct sockaddr_in6 *sa = (struct sockaddr_in6 *)_ai->ai_addr;
+ NSString *buf = [[NSMutableString alloc] initWithFormat:nsfmt,_ai->ai_flags,_ai->ai_family,_ai->ai_socktype,_ai->ai_protocol,_ai->ai_canonname?_ai->ai_canonname:"",sa->sin6_len,sa->sin6_family,sa->sin6_port,sa->sin6_flowinfo,sa->sin6_addr.__u6_addr.__u6_addr16[0],sa->sin6_addr.__u6_addr.__u6_addr16[1],sa->sin6_addr.__u6_addr.__u6_addr16[2],sa->sin6_addr.__u6_addr.__u6_addr16[3],sa->sin6_addr.__u6_addr.__u6_addr16[4],sa->sin6_addr.__u6_addr.__u6_addr16[5],sa->sin6_addr.__u6_addr.__u6_addr16[6],sa->sin6_addr.__u6_addr.__u6_addr16[7],sa->sin6_scope_id,_ai->ai_next?[self dumpv6Addrinfo:_ai->ai_next]:@"nil"];
- do
- {
- struct sockaddr_in6 *sa = (struct sockaddr_in6 *)_ai->ai_addr;
- [buf appendFormat:nsfmt,_ai->ai_flags,_ai->ai_family,_ai->ai_socktype,_ai->ai_protocol,_ai->ai_canonname?_ai->ai_canonname:"",sa->sin6_len,sa->sin6_family,sa->sin6_port,sa->sin6_flowinfo,sa->sin6_addr.__u6_addr.__u6_addr16[0],sa->sin6_addr.__u6_addr.__u6_addr16[1],sa->sin6_addr.__u6_addr.__u6_addr16[2],sa->sin6_addr.__u6_addr.__u6_addr16[3],sa->sin6_addr.__u6_addr.__u6_addr16[4],sa->sin6_addr.__u6_addr.__u6_addr16[5],sa->sin6_addr.__u6_addr.__u6_addr16[6],sa->sin6_addr.__u6_addr.__u6_addr16[7],sa->sin6_scope_id];
- }
- while (_ai = _ai->ai_next);
- [buf appendString:@"nil\n}"];
return buf;
}
@end
const char *portNam = [namedPort cString], *hostCStr = [host cString];
hints.ai_flags = 0;
- hints.ai_family = PF_INET6;
+ hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
+ hints.ai_addrlen = 0;
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
err = getaddrinfo(hostCStr,portNam,&hints,&ai);
- if (err == EAI_NODATA) //it's a dotted-decimal IPv4 string, so we use v6compat stuff now
- {
- err = getaddrinfo([[NSString stringWithFormat:@"ffff::%s",hostCStr] cString],portNam,&hints,&ai);
- }
- NSLog([self dumpv6Addrinfo:ai]);
+
+ NSLog(@"%s, h %@ p %@",gai_strerror(err),host,namedPort);
+ NSLog(ai?[self dumpv6Addrinfo:ai]:@"");
+ ai_cur = ai;
+ [self realDoConnection];
+}
+
+-(void)realDoConnection
+{
+ sockfd = socket(ai_cur->ai_addr->sa_family,SOCK_STREAM,IPPROTO_TCP);
+ [self spinoffReadLoop];
}
-(void)spinoffReadLoop
{
NSAutoreleasePool *ap = [[NSAutoreleasePool alloc] init];
NSConnection *dcon = [[NSConnection alloc] initWithReceivePort:[data objectAtIndex:0] sendPort:[data objectAtIndex:1]];
- NSProxy *dp = [dcon rootProxy];
+ NSProxy *dp = [[dcon rootProxy] retain];
char *buf = malloc(bufs);
unsigned long readLen = 0;
-
+ signed int err;
+ [readPipe setDelegate:dp];
+ NSLog(@"Connecting");
+ err = connect(sockfd,ai_cur->ai_addr,ai_cur->ai_addrlen);
+ if (err == -1)
+ {
+ perror("CAwh");
+ [(id)dp errorOccured:ITInetCouldNotConnect during:ITInetSocketConnecting onSocket:self];
+ goto dieaction;
+ }
+ NSLog(@"Sending finishedConnecting");
+ [(id)dp finishedConnecting:self];
lstart:
- do
+
+ while (!actionflag && !dieflag)
{
- NSData *d = [NSData alloc];
+ NSData *d;
readLen = recv(sockfd,buf,bufs,0);
- [d initWithBytesNoCopy:buf length:readLen];
- [readPipe writeData:d];
- [d release];
- [dp dataRecieved:self];
+ if (readLen == -1) {[(id)dp errorOccured:ITInetConnectionDropped during:ITInetSocketReading onSocket:self];goto dieaction;}
+ if (readLen) {
+ NSLog(@"recv'd");
+ NSLog(@"Doing writeData to readPipe");
+ [readPipe writeBytes:buf len:readLen];
+ [ap release];
+ ap = [[NSAutoreleasePool alloc] init];
+ }
}
- while (!actionflag);
+
actionflag = 0;
+
if (dieflag)
{
+dieaction:
+ perror("Awh");
free(buf);
+ shutdown(sockfd,2);
[dcon release];
+ [dp release];
[ap release];
dieflag = 0;
return;
}
{
+ NSLog(@"Emptying writePipe");
NSData *d = [writePipe readAllData];
write(sockfd,[d bytes],[d length]);
+ [ap release];
+ ap = [[NSAutoreleasePool alloc] init];
goto lstart;
}
+ goto dieaction;
}
@end
\ No newline at end of file