Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // MHProxyFactory.m
- // MineHelmet
- //
- // Created by Dylan Lukes on 10/22/10.
- // Copyright 2010 Dylan Lukes. All rights reserved.
- //
- #import "MHProxyManager.h"
- #import "APELite.h"
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netdb.h>
- typedef struct{
- int client;
- int server;
- } MHProxyDescriptorPair;
- @interface MHProxyManager (PrivateMethods)
- - (int)handleConnectAttempt:(int)socket addr:(const struct sockaddr *)addr addrlen:(socklen_t)addrlen;
- - (void)proxyThreadMain:(NSValue *)pairValue;
- @end
- static MHProxyManager *instance_pointer;
- static int connect_override(int socket, const struct sockaddr *address, socklen_t addrlen){
- return [instance_pointer handleConnectAttempt:socket addr:address addrlen:addrlen];
- }
- @implementation MHProxyManager
- + (id)sharedInstance {
- static dispatch_once_t pred;
- static MHProxyManager *instance = nil;
- dispatch_once(&pred, ^{ instance = [[self alloc] init]; });
- return instance;
- }
- - (id)init {
- if (self = [super init]) {
- connectReentry = APEPatchCreate(connect, connect_override);
- instance_pointer = self;
- }
- return self;
- }
- - (int)handleConnectAttempt:(int)socket addr:(const struct sockaddr *)addr addrlen:(socklen_t)addrlen {
- static BOOL javaStackTestConnect = NO;
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- // Ignore the first connect() attempt (java test)
- static dispatch_once_t pred;
- dispatch_once(&pred, ^{javaStackTestConnect = YES;});
- if (javaStackTestConnect) {
- javaStackTestConnect = NO;
- return connectReentry(socket, addr, addrlen);
- }
- char serv[NI_MAXSERV];
- // If the socket is not for minecraft, return without doing anything...
- getnameinfo(addr, addrlen, NULL, 0, serv, NI_MAXSERV, NI_NUMERICSERV);
- int port = atoi(serv);
- if (port == 80) {
- return connectReentry(socket, addr, addrlen);
- }
- // if socket is non-blocking...
- BOOL wasNonBlocking = NO;
- int flags = fcntl(socket,F_GETFL);
- if (flags & O_NONBLOCK){
- wasNonBlocking = YES;
- fcntl(socket, F_SETFL, flags & ~O_NONBLOCK);
- }
- // Call the original connect()
- int retval = connectReentry(socket, addr, addrlen);
- // Steal the original file descriptor (to server)
- int original_fd = dup(socket);
- // Redirect socket to sockpair[0]
- int sockpair[2];
- socketpair(AF_UNIX, SOCK_STREAM, 0, sockpair);
- dup2(sockpair[0], socket);
- // If the socket was non-blocking...
- if (wasNonBlocking) {
- // ...fix the socket to its original state
- fcntl(socket, F_SETFL, O_NONBLOCK);
- }
- // Set up proxy
- MHProxyDescriptorPair pair = {sockpair[1], original_fd};
- NSValue *pairValue = [NSValue value:&pair withObjCType:@encode(MHProxyDescriptorPair)];
- [NSThread detachNewThreadSelector:@selector(proxyThreadMain:) toTarget:self withObject:pairValue];
- [pool drain];
- return retval;
- }
- - (void)proxyThreadMain:(NSValue *)pairValue{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [[NSThread currentThread] setName:@"MineHelmet Proxy Thread"];
- MHProxyDescriptorPair pair;
- [pairValue getValue:&pair];
- proxy = [[MHProxy alloc] initWithClientDescriptor:pair.client serverDescriptor:pair.server];
- // Run loop
- CFRunLoopRun();
- // When the proxy stops the loop, release it
- [proxy release];
- [pool drain];
- }
- @end
Add Comment
Please, Sign In to add comment