rld.c
上传用户:sddyfurun
上传日期:2007-01-04
资源大小:525k
文件大小:14k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /* Copyright (c) 1995,1996,1997 NEC Corporation.  All rights reserved.       */
  2. /*                                                                           */
  3. /* The redistribution, use and modification in source or binary forms of     */
  4. /* this software is subject to the conditions set forth in the copyright     */
  5. /* document ("Copyright") included with this distribution.                   */
  6. /*
  7.  * $Id: rld.c,v 1.33.4.4 1998/11/14 00:06:23 steve Exp $
  8.  */
  9. /* This file has all the stubs to get the "real" functions out of libc,      */
  10. /* libnsl or libsocket.  Sometimes we need the "real" function, because      */
  11. /* we've replaced it (i.e. connect), sometimes we need it because we will    */
  12. /* have mangled some static data that it keeps around (i.e. getenv).         */
  13. #include "socks5p.h"
  14. #include "addr.h"
  15. #include "log.h"
  16. #ifdef HAVE_DLOPEN
  17. #include <dlfcn.h>
  18. #ifndef RTLD_LAZY
  19. #define RTLD_LAZY 1
  20. #endif
  21. #ifndef RTLD_GLOBAL
  22. #define RTLD_GLOBAL 0
  23. #endif
  24. #ifndef LIBC_NAME
  25. #define LIBC_NAME NULL
  26. #endif
  27. #ifndef LIBNSL_NAME
  28. #define LIBNSL_NAME NULL
  29. #endif
  30. #ifndef LIBRESOLV_NAME
  31. #define LIBRESOLV_NAME NULL
  32. #endif
  33. #ifndef LIBSOCKET_NAME
  34. #define LIBSOCKET_NAME NULL
  35. #endif
  36. #ifndef LIBDGC_NAME
  37. #define LIBDGC_NAME NULL
  38. #endif
  39. /* Lets hope we don't have to do this for too many OS's...Maybe configure    */
  40. /* should figure it out...?                                                  */
  41. #define TRY_LIBC        (1 << 0)
  42. #define TRY_LIBNSL      (1 << 1)
  43. #define TRY_LIBSOCKET   (1 << 2)
  44. #define TRY_LIBRESOLV   (1 << 3)
  45. #define NO_RTLD_NEXT    (1 << 4)
  46. #define USE_RTLD_GLOBAL (1 << 5)
  47. #ifdef FOR_SHARED_LIBRARY
  48. #define GETSYM(handle, libname, flags)                                       
  49.      if (!(handle) && ((handle) = dlopen((libname), (flags))) == NULL) {     
  50. return;      
  51.      } else if ((*fptr = dlsym((handle), name)) != NULL) {                   
  52.         return;                                                              
  53.      } else
  54.  
  55. #define DGETSYM(handle, libname, flags)                                      
  56.      if (!(handle) && ((handle) = dlopen((libname), (flags))) == NULL) {     
  57. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Unable to open shared library: %s", (libname)); 
  58.      } else if ((*fptr = dlsym((handle), name)) != NULL) {                   
  59. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Found %s in %s%s", name, (libname), libmask&USE_RTLD_GLOBAL?"(g)":"");  
  60.         return;                                                              
  61.      } else
  62.  
  63. #define GETSYMHANDLE(mask, handle, libname, envname, flags)                  
  64.     if (libmask & (mask)) {                                                  
  65. static void *(handle) = NULL;                                        
  66.         char *lname = (envname)?getenv((envname)):NULL;                      
  67. if (lname == NULL) lname = (libname);                                
  68.         if (lname) GETSYM((handle), lname, (flags));                         
  69.     } else
  70. #define DGETSYMHANDLE(mask, handle, libname, envname, flags)                 
  71.     if (libmask & (mask)) {                                                  
  72. static void *(handle) = NULL;                                        
  73.         char *lname = (envname)?getenv((envname)):NULL;                      
  74. if (lname == NULL) lname = (libname);                                
  75.         if (lname) DGETSYM((handle), lname, (flags));                        
  76.     } else
  77. #define GETFUNC(name, flags, invalid, cast, args, rtype)                     
  78.     static void *func = NULL;                                                
  79.     static rtype rval;                                                       
  80.     GetOriginalFunc(&func, (name), (flags));                                 
  81.     if (!func || func == (void *)-1) return (invalid);                       
  82.     lsInRLDFunctions = 1;                                                      
  83.     rval = (cast func)args;                                                  
  84.     lsInRLDFunctions = 0;                                                      
  85.     return rval
  86. #define DGETFUNC(name, flags, invalid, cast, args, rtype)                    
  87.     static void *func = NULL;                                                
  88.     static rtype rval;                                                       
  89.     DGetOriginalFunc(&func, (name), (flags));                                 
  90.     if (!func || func == (void *)-1) return (invalid);                       
  91.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "RLD: Found %s at %p", (name)+1, func);     
  92.     lsInRLDFunctions = 1;                                                      
  93.     rval = (cast func)args;                                                  
  94.     lsInRLDFunctions = 0;                                                      
  95.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "RLD: %s returned: %x", (name)+1, (rval));  
  96.     return rval
  97. extern int lsInRLDFunctions;
  98. /* strips pathname, returns relative path  */
  99. /* absolutepath must be null terminated    */
  100. char* StripPath(char* absolutepath) {
  101.   int i;
  102.   if (absolutepath==NULL) return absolutepath;
  103.   for (i = strlen(absolutepath); i>=0; i--) {
  104.     if (absolutepath[i]=='/') {
  105.       return &absolutepath[i+1];
  106.     }
  107.   }
  108.   return absolutepath;
  109. }
  110. /* Look up name in libc.so, libnsl.so, and libsocket.so, if its there return */
  111. /* the symbol we found, otherwise return NULL...                             */
  112. static void GetOriginalFunc(void **fptr, char *name, int libmask) {
  113.     /* Synchronize access to func and lib opening functions if we can...     */
  114. #ifndef __FreeBSD__
  115.     name++;
  116. #endif
  117.     if (*fptr) return;
  118.     /* Still have to figure out what OSs USE_RTLD_NEXT is valid for.  For    */
  119.     /* most that I've tried, it hasn't worked right...                       */
  120. #if defined(RTLD_NEXT) && defined(USE_RTLD_NEXT)
  121.     if (name && ~libmask & NO_RTLD_NEXT && (*fptr = dlsym(RTLD_NEXT, name)) != NULL) {
  122.         return;
  123.     }
  124. #endif
  125.     GETSYMHANDLE(TRY_LIBRESOLV, libresolv_handle, StripPath(LIBRESOLV_NAME),  "LIBRESOLV_NAME", RTLD_LAZY);
  126.     GETSYMHANDLE(TRY_LIBNSL,    libnsl_handle,    StripPath(LIBNSL_NAME),     "LIBNSL_NAME",    RTLD_LAZY);
  127.     GETSYMHANDLE(TRY_LIBSOCKET, libsocket_handle, StripPath(LIBSOCKET_NAME),  "LIBSOCKET_NAME", RTLD_LAZY);
  128.     GETSYMHANDLE(TRY_LIBSOCKET, libdgc_handle,    StripPath(LIBDGC_NAME),     "LIBDGC_NAME",    RTLD_LAZY);
  129.     GETSYMHANDLE(TRY_LIBC,      libc_handle,      StripPath(LIBC_NAME),       "LIBC_NAME",      RTLD_LAZY);
  130. }
  131. /* Look up name in libc.so, libnsl.so, and libsocket.so, if its there return */
  132. /* the symbol we found, otherwise return NULL...                             */
  133. static void DGetOriginalFunc(void **fptr, char *name, int libmask) {
  134.     /* Synchronize access to func and lib opening functions if we can...     */
  135. #ifndef __FreeBSD__
  136.     name++;
  137. #endif
  138.     if (*fptr) return;
  139.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "RLD: %s", name);
  140.     /* Still have to figure out what OSs USE_RTLD_NEXT is valid for.  For    */
  141.     /* most that I've tried, it hasn't worked right...                       */
  142. #if defined(RTLD_NEXT) && defined(USE_RTLD_NEXT)
  143.     if (name && ~libmask & NO_RTLD_NEXT && (*fptr = dlsym(RTLD_NEXT, name)) != NULL) {
  144. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "RLD: Used RTLD_NEXT");
  145.         return;
  146.     }
  147. #endif
  148.     DGETSYMHANDLE(TRY_LIBRESOLV, libresolv_handle, StripPath(LIBRESOLV_NAME),  "LIBRESOLV_NAME", RTLD_LAZY);
  149.     DGETSYMHANDLE(TRY_LIBNSL,    libnsl_handle,    StripPath(LIBNSL_NAME),     "LIBNSL_NAME",    RTLD_LAZY);
  150.     DGETSYMHANDLE(TRY_LIBSOCKET, libsocket_handle, StripPath(LIBSOCKET_NAME),  "LIBSOCKET_NAME", RTLD_LAZY);
  151.     DGETSYMHANDLE(TRY_LIBSOCKET, libdgc_handle,    StripPath(LIBDGC_NAME),     "LIBDGC_NAME",    RTLD_LAZY);
  152.     DGETSYMHANDLE(TRY_LIBC,      libc_handle,      StripPath(LIBC_NAME),       "LIBC_NAME",      RTLD_LAZY);
  153.     
  154.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "RLD: Unable to find symbol %s in suggested places: %d", name, libmask);
  155. }
  156. struct hostent *REAL(gethostbyname)(const char *name) {
  157.     struct hostent *hp;
  158.     static void *func = NULL;
  159.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "RLD: gethostbyname: %s", name);
  160.     GetOriginalFunc(&func, "_gethostbyname", TRY_LIBC | TRY_LIBNSL | TRY_LIBRESOLV);
  161.     if (!func || func == (void *)-1) return NULL;
  162.     lsInRLDFunctions = 1;
  163.     hp = ((struct hostent *(*)P((const char *)))func)(name);
  164.     lsInRLDFunctions = 0;
  165.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "RLD: gethostbyname results: %s %s", name, hp?hp->h_name:"???");
  166.     return hp;
  167. }
  168. int REAL(getpeername) (S5IOHandle sd, ss *sa, int *slen) {
  169.     GETFUNC("_getpeername", TRY_LIBC | TRY_LIBSOCKET,  -1, (int (*)P((S5IOHandle, ss *, int *))),                            (sd, sa, slen), int);
  170. }
  171. int REAL(getsockname) (S5IOHandle sd, ss *sa, int *slen) {
  172.     GETFUNC("_getsockname", TRY_LIBC | TRY_LIBSOCKET, -1,  (int (*)P((S5IOHandle, ss *, int *))),                            (sd, sa, slen), int);
  173. }
  174.     
  175. int REAL(accept)      (S5IOHandle sd, ss *sa, int *slen) {
  176.     GETFUNC("_accept",      TRY_LIBC | TRY_LIBSOCKET,  -1, (int (*)P((S5IOHandle, ss *, int *))),                            (sd, sa, slen), int);
  177. }
  178. int REAL(connect)     (S5IOHandle sd, const ss *sa, int slen) {
  179.     GETFUNC("_connect",     TRY_LIBC | TRY_LIBSOCKET, -1,  (int (*)P((S5IOHandle, const ss *, int))),                        (sd, sa, slen), int);
  180. }
  181. int REAL(bind)        (S5IOHandle sd, const ss *sa, int slen) {
  182.     GETFUNC("_bind",        TRY_LIBC | TRY_LIBSOCKET, -1,  (int (*)P((S5IOHandle, const ss *, int))),                        (sd, sa, slen), int);
  183. }
  184. int REAL(recvfrom)    (S5IOHandle sd, IOPTRTYPE buf, IOLENTYPE blen, int f, ss *sa, int *slen) {
  185.     GETFUNC("_recvfrom",    TRY_LIBC | TRY_LIBSOCKET, -1, (int (*)P((S5IOHandle, char *, int, int, ss *, int *))),           (sd, buf, blen, f, sa, slen), int);
  186. }
  187. int REAL(sendto)      (S5IOHandle sd, const IOPTRTYPE buf, IOLENTYPE blen, int f, const ss *sa, int slen) {
  188.     GETFUNC("_sendto",      TRY_LIBC | TRY_LIBSOCKET, -1, (int (*)P((S5IOHandle, const char *, int, int, const ss *, int))), (sd, buf, blen, f, sa, slen), int);
  189. }
  190. #ifdef HAVE_SENDMSG
  191. int REAL(recvmsg)    (S5IOHandle sd, const ms *sa, int slen) {
  192.     GETFUNC("_recvmsg",    TRY_LIBC | TRY_LIBSOCKET, -1, (int (*)P((S5IOHandle, const ms *, int ))),           (sd, sa, slen), int);
  193. }
  194. int REAL(sendmsg)      (S5IOHandle sd, const ms *sa, int slen) {
  195.     GETFUNC("_sendmsg",      TRY_LIBC | TRY_LIBSOCKET, -1, (int (*)P((S5IOHandle, const ms *, int))), (sd, sa, slen), int);
  196. }
  197. #endif
  198. int REAL(recv)        (S5IOHandle sd, IOPTRTYPE buf, IOLENTYPE blen, int f) {
  199.     GETFUNC("_recv",        TRY_LIBC | TRY_LIBSOCKET, -1, (int (*)P((S5IOHandle, char *, int, int))),                        (sd, buf, blen, f), int);
  200. }
  201. int REAL(send)        (S5IOHandle sd, const IOPTRTYPE buf, IOLENTYPE blen, int f) {
  202.     GETFUNC("_send",        TRY_LIBC | TRY_LIBSOCKET, -1, (int (*)P((S5IOHandle, const char *, int, int))),                  (sd, buf, blen, f), int);
  203. }
  204. int REAL(shutdown)    (S5IOHandle sd, int how) {
  205.     GETFUNC("_shutdown",    TRY_LIBC | TRY_LIBSOCKET, -1, (int (*)P((S5IOHandle, int))),                                     (sd, how), int);
  206. }
  207. int REAL(listen)      (S5IOHandle sd, int n) {
  208.     GETFUNC("_listen",      TRY_LIBC | TRY_LIBSOCKET, -1, (int (*)P((S5IOHandle, int))),                                     (sd, n), int);
  209. }
  210. S5IOHandle REAL(dup)  (S5IOHandle sd) {
  211.     GETFUNC("_dup",          TRY_LIBC,                S5InvalidIOHandle, (S5IOHandle (*)P((S5IOHandle))),                    (sd), S5IOHandle);
  212. }
  213. S5IOHandle REAL(dup2) (S5IOHandle sd, S5IOHandle s2) {
  214.     GETFUNC("_dup2",         TRY_LIBC,                S5InvalidIOHandle, (S5IOHandle (*)P((S5IOHandle, S5IOHandle))),        (sd, s2), S5IOHandle);
  215. }
  216. int REAL(close)       (S5IOHandle sd) {
  217.     GETFUNC("_close",       TRY_LIBC,                 -1, (int (*)P((S5IOHandle))),                                          (sd), int);
  218. }
  219. int REAL(fclose)      (FILE *fp) {
  220.     GETFUNC("_fclose",     TRY_LIBC,                  -1, (int (*)P((FILE *))),                                              (fp), int);
  221. }
  222. IORETTYPE REAL(read)  (S5IOHandle sd, IOPTRTYPE buf, IOLENTYPE blen) {
  223.     GETFUNC("_read",         TRY_LIBC,                -1, (IORETTYPE (*)P((S5IOHandle, IOPTRTYPE, IOLENTYPE))),              (sd, buf, blen), IORETTYPE);
  224. }
  225. IORETTYPE REAL(write) (S5IOHandle sd, const IOPTRTYPE buf, IOLENTYPE blen) {
  226.     GETFUNC("_write",        TRY_LIBC,                -1, (IORETTYPE (*)P((S5IOHandle, const IOPTRTYPE, IOLENTYPE))),        (sd, buf, blen), IORETTYPE);
  227. }
  228. struct tm *REAL(localtime)(const time_t *clock) {
  229.     static void *func = NULL;
  230.     static struct tm * rval;
  231.     GetOriginalFunc(&func, "_localtime", TRY_LIBC);
  232.     if (!func || func == (void *)-1) return (NULL);
  233.     lsInRLDFunctions = 1;
  234.     rval = ((struct tm * (*)(const time_t *))func)(clock);
  235.     lsInRLDFunctions = 0;
  236.     return rval;
  237. }
  238. void REAL(longjmp) (jmp_buf env, int val) {
  239.     static void *func = NULL;
  240.     GetOriginalFunc(&func, "_longjmp", TRY_LIBC);
  241.     if (!func || func == (void *)-1) return; 
  242.     lsInRLDFunctions = 0;
  243.     ((void (*)(jmp_buf, int))func)(env, val);
  244. }
  245. int REAL(select)      (S5IOHandle wd, fd_set *rs, fd_set *ws, fd_set *es, struct timeval *to) {
  246.     GETFUNC("_select",       TRY_LIBC,                -1, (int (*)P((S5IOHandle, fd_set *, fd_set *, fd_set *, struct timeval *))), (wd, rs, ws, es, to), int);
  247. }
  248. #ifdef HAVE_RRESVPORT
  249. S5IOHandle REAL(rresvport)   (int *port) {
  250.     GETFUNC("_rresvport",   TRY_LIBC | TRY_LIBSOCKET, S5InvalidIOHandle, (S5IOHandle (*)P((int *))),                         (port), S5IOHandle);
  251. }
  252. #endif
  253. #endif /* FOR_SHARED_LIBRARY                                                 */
  254. #endif /* HAVE_DLOPEN        */