Annotation of libwww/Library/src/HTNet.html, revision 2.44.2.1
2.1 frystyk 1: <HTML>
2: <HEAD>
2.43 frystyk 3: <TITLE>W3C Reference Library libwww HTNet Class</TITLE>
2.1 frystyk 4: </HEAD>
5: <BODY>
2.43 frystyk 6: <H1>
7: The Net Class
2.36 eric 8: </H1>
2.5 frystyk 9: <PRE>
10: /*
2.8 frystyk 11: ** (c) COPYRIGHT MIT 1995.
2.5 frystyk 12: ** Please first read the full copyright statement in the file COPYRIGH.
13: */
14: </PRE>
2.36 eric 15: <P>
2.38 frystyk 16: The Net class manages information related to a "thread" in libwww. As libwww
17: threads are not really threads but a notion of using interleaved, non-blocking
18: I/O for accessing data objects from the network (or local file system), they
19: can be used on any platform with or without support for native threads. In
20: the case where you have an application using real threads the Net class is
21: simply a object maintaining links to all other objects involved in serving
22: the request. If you are using the libwww pseudo threads then the Net object
23: contains enough information to stop and start a request based on which BSD
24: sockets are ready. In practise this is of course transparent to the application
25: - this is just to explain the difference.
26: <P>
27: When a <A HREF="HTReq.html">Request object</A> is passed to the Library ,
28: the core creates a new HTNet object pr <A HREF="HTChannl.html">channel</A>
29: used by the request. In many cases a request only uses a single
30: <A HREF="HTChannl.html">channel object </A>but for example FTP requests use
31: at least two - one for the control connection and one for the data connection.
32: <P>
33: You can find more information about the libwww pseudo thread model in the
34: <A HREF="../User/Architecture/"> Multithread Specifications</A>.
2.36 eric 35: <P>
36: This module is implemented by <A HREF="HTNet.c">HTNet.c</A>, and it is a
37: part of the <A HREF="http://www.w3.org/pub/WWW/Library/">W3C Reference
38: Library</A>.
2.1 frystyk 39: <PRE>
2.17 frystyk 40: #ifndef HTNET_H
41: #define HTNET_H
2.1 frystyk 42: </PRE>
2.36 eric 43: <P>
44: The <CODE>HTNet</CODE> object is the core of the request queue management.
45: This object contains information about the socket descriptor, the input read
46: buffer etc. required to identify and service a request.
2.1 frystyk 47: <PRE>
2.18 frystyk 48: typedef struct _HTNet HTNet;
2.34 frystyk 49:
2.36 eric 50: #include "HTEvent.h"
2.34 frystyk 51: #include "HTReq.h"
2.44 frystyk 52: #include "HTResponse.h"
2.34 frystyk 53: #include "HTTrans.h"
54: #include "HTHost.h"
55: #include "HTChannl.h"
56: #include "HTDNS.h"
2.1 frystyk 57: </PRE>
2.36 eric 58: <H2>
2.44 frystyk 59: <A NAME="callout">Generic BEFORE and AFTER Filter Management</A>
2.36 eric 60: </H2>
61: <P>
2.43 frystyk 62: Filter functions can be registered to be called <EM>before</EM> and
2.44 frystyk 63: <EM>after</EM> a request has either been started or has terminated. The
64: conditions for <I>BEFORE</I> and <I>AFTER</I> filters are not the same so
65: we maintain them independently. Filters can be registered globally or locally.
66: The global filters are registered directly by the Net Object (this module)
67: and the local filters are registered by the
68: <A HREF="HTReq.html">HTRequest</A> Object. However, both local and
69: global filters use the same regisration mechanism which we provide here.
70: <H3>
71: Filter Ordering
72: </H3>
73: <P>
74: Filters can be registered by anyone and as they are an often used mechanism
75: for introducing extensions in libwww, they are videly used to handle
76: authentication, redirection, etc. Many filters can be registered at once
77: and not all of the filters may know about the other filters. Therefore, it
78: is difficult to specify an absolute ordering by which the filters should
79: be called. Instead you can decide a relative order by which the filters should
80: be called. The order works pretty much like the Unix priority mechanism running
81: from <CODE>HT_FILTER_FIRST</CODE> to <CODE>HT_FILTER_LAST</CODE> having
82: <CODE>HT_FILTER_MIDDLE</CODE> being the "normal" case.
83: <PRE>
84: #define HT_FILTER_FIRST 0
85: #define HT_FILTER_MIDDLE 5
86: #define HT_FILTER_LAST 10
87: </PRE>
88: <P>
89: In case multiple filters are registered with the same order then they are
90: called in the <I>inverse</I> order they were registered.
91: <H3>
92: Filter URL Templates
93: </H3>
94: <P>
95: Both <I>BEFORE</I> and <I>AFTER</I> filters can be registered with a <I>URL
96: template</I> in which case they are only called when the <I>Request URL</I>
97: matches the template. A template is simply a string which is matched against
98: the <I>Request URL</I>. The string can be terminated by a single
99: "<CODE>*</CODE>" in which case all strings matching the template up til the
100: "*" is considered a match. A template can be as short as the access scheme
101: which enmables a filter for a specific access method only, for example
102: "<CODE>http//<star></CODE>".
103: <H3>
104: BEFORE Filters
105: </H3>
106: <P>
107: A <I>BEFORE</I> filter is called whenever we issue a request and they have
108: been selected by the execution procedure. <I>BEFORE</I> filters are registered
109: with a <I>context</I> and a <I>filter order</I> by which they are to be called
110: and a <I>URL template</I> which may be NULL. In this case, the filter is
111: called on every request. The mode can be used by anybody to pass an extra
112: parameter to a filter. This is not really OO thinking - but hey - this is C ;-)
113: <PRE>typedef int HTNetBefore (HTRequest * request, void * param, int mode);
114: </PRE>
115: <P>
116: You can add a <I>BEFORE</I> filter in the list provided by the caller. Several
117: filters can be registered in which case they are called with the filter ordering
118: in mind.
119: <PRE>
120: extern BOOL HTNetCall_addBefore (HTList * list, HTNetBefore * before,
121: const char * tmplate, void * param,
122: int order);
123: </PRE>
124: <P>
125: You can also unregister all instances of a BEFORE filter from a list using
126: the following function
127: <PRE>
128: extern BOOL HTNetCall_deleteBefore (HTList * list, HTNetBefore * before);
129: </PRE>
130: <P>
131: You get rid of all BEFORE filters usign this function
132: <PRE>
133: extern BOOL HTNetCall_deleteBeforeAll (HTList * list);
134: </PRE>
135: <P>
136: The BEFORE filters are expected and called if appropriate every time we issue
137: a new request. Libwww calls the BEFORE filters in the order specified at
138: registration time. If a filter returns other than HT_OK then stop and return
139: immediately. Otherwise return what the last filter returns.
140: <PRE>
141: extern int HTNetCall_executeBefore (HTList * list, HTRequest * request);
142: </PRE>
143: <H3>
144: AFTER Filters
145: </H3>
146: <P>
147: An <I>AFTER</I> filter is called whenever we have terminated a request. That
148: is, on the way out from the <A HREF="HTProt.html">protocol module</A> and
149: back to the application. <I>AFTER</I> filters are registered with a
150: <I>context</I>, a <I>status</I>, a <I>filter order</I> by which they are
151: to be called and a <I>URL template</I> which may be NULL. The status of the
152: request may determine which filter to call. The set of possible values are
153: given below. An <I>AFTER</I> filter can be registered to handle one or more
154: of the codes.
2.17 frystyk 155: <DL>
2.36 eric 156: <DT>
157: HT_ERROR
158: <DD>
159: An error occured
160: <DT>
161: HT_LOADED
162: <DD>
163: The document was loaded
164: <DT>
165: HT_NO_DATA
166: <DD>
167: OK, but no data
168: <DT>
2.43 frystyk 169: HT_NO_ACCESS
170: <DD>
171: The request could not be succeeded due to lack of credentials
172: <DT>
173: HT_NO_PROXY_ACCESS
174: <DD>
175: The request could not be succeeded due to lack of credentials for accessing
176: an intermediate proxy
177: <DT>
2.36 eric 178: HT_RETRY
179: <DD>
180: Retry request after at a later time
181: <DT>
2.40 frystyk 182: HT_PERM_REDIRECT
2.36 eric 183: <DD>
2.40 frystyk 184: The request has been permanently redirected and we send back the new URL
185: <DT>
186: HT_TEMP_REDIRECT
187: <DD>
188: The request has been temporaryly redirected and we send back the new URL
2.36 eric 189: <DT>
190: HT_ALL
191: <DD>
192: All of above
2.17 frystyk 193: </DL>
2.36 eric 194: <P>
2.44 frystyk 195: A Protocol module can also in certain cases return a <CODE>HT_IGNORE </CODE>in
196: which case no filters are called
197: <PRE>
198: typedef int HTNetAfter (HTRequest * request, HTResponse * response,
199: void * param, int status);
200: </PRE>
201: <P>
202: You can register a AFTER filter in the list provided by the caller. Several
203: filters can be registered in which case they are called with the filter ordering
204: in mind.
2.1 frystyk 205: <PRE>
2.44 frystyk 206: extern BOOL HTNetCall_addAfter (HTList * list, HTNetAfter * after,
207: const char * tmplate, void * param,
208: int status, int order);
2.9 frystyk 209: </PRE>
2.36 eric 210: <P>
2.44 frystyk 211: You can either unregister all filters registered for a given status using this function or the filter for all status codes.
2.9 frystyk 212: <PRE>
2.44 frystyk 213: extern BOOL HTNetCall_deleteAfter (HTList * list, HTNetAfter * after);
214: extern BOOL HTNetCall_deleteAfterStatus (HTList * list, int status);
2.1 frystyk 215: </PRE>
2.36 eric 216: <P>
2.44 frystyk 217: You can also delete all AFTER filters in list
2.24 frystyk 218: <PRE>
2.44 frystyk 219: extern BOOL HTNetCall_deleteAfterAll (HTList * list);
2.24 frystyk 220: </PRE>
2.36 eric 221: <P>
2.44 frystyk 222: This function calls all the AFTER filters in the order specified at registration
223: time and if it has the right status code and it's not <CODE>HT_IGNORE</CODE>.
224: We also check for any template and whether it matches or not. If a filter
225: returns other than HT_OK then stop and return immediately. Otherwise return
226: what the last filter returns.
2.24 frystyk 227: <PRE>
2.44 frystyk 228: extern int HTNetCall_executeAfter (HTList * list, HTRequest * request,
229: int status);
2.24 frystyk 230: </PRE>
2.44 frystyk 231: <H2>
232: Global BEFORE and AFTER Filter Management
233: </H2>
234: <P>
235: Global filters are inspected on every request (they do not have to be called
236: - only if the conditions match). You can also register filters locally in
237: the Request object.
238: <H4>
239: Global BEFORE Filters
240: </H4>
2.36 eric 241: <P>
2.44 frystyk 242: These are the methods to handle global <I>BEFORE</I> Filters.
2.24 frystyk 243: <PRE>
2.44 frystyk 244: extern BOOL HTNet_setBefore (HTList * list);
245:
246: extern HTList * HTNet_before (void);
2.42 frystyk 247:
2.44 frystyk 248: extern BOOL HTNet_addBefore (HTNetBefore * before, const char * tmplate,
249: void * param, int order);
2.42 frystyk 250:
2.44 frystyk 251: extern BOOL HTNet_deleteBefore (HTNetBefore * before);
2.24 frystyk 252: </PRE>
2.36 eric 253: <P>
2.44 frystyk 254: You can call both the local and the global BEFORE filters (if any)
255: <PRE>
256: extern int HTNet_executeBeforeAll (HTRequest * request);
257: </PRE>
258: <H4>
259: Global AFTER Filters
260: </H4>
261: <P>
262: These are the methods to handle global <I>AFTER</I> Filters.
2.10 frystyk 263: <PRE>
2.44 frystyk 264: extern BOOL HTNet_setAfter (HTList * list);
265:
266: extern HTList * HTNet_after (void);
267:
268: extern BOOL HTNet_addAfter (HTNetAfter * after, const char * tmplate,
269: void * param, int status, int order);
2.42 frystyk 270:
2.44 frystyk 271: extern BOOL HTNet_deleteAfter (HTNetAfter * after);
2.42 frystyk 272:
2.44 frystyk 273: extern BOOL HTNet_deleteAfterStatus (int status);
274: </PRE>
275: <P>
276: You can call both the local and the global AFTER filters (if any)
277: <PRE>
278: extern int HTNet_executeAfterAll (HTRequest * request, int status);
2.10 frystyk 279: </PRE>
2.36 eric 280: <H2>
2.43 frystyk 281: Socket Resource Management
2.36 eric 282: </H2>
283: <P>
284: The request queue ensures that no more than a fixed number of TCP connections
285: are open at the same time. If more requests are handed to the Library, they
286: are put into the pending queue and initiated when sockets become free.
287: <H3>
288: Number of Simultanous open TCP connections
289: </H3>
290: <P>
291: Set the max number of simultanous sockets. The default value is HT_MAX_SOCKETS
292: which is 6. The number of persistent connections depend on this value as
293: a deadlock can occur if all available sockets a persistent (see the
294: <A HREF="HTDNS.html">DNS Manager</A> for more information on setting the
295: number of persistent connections). The number of persistent connections can
296: never be more than the max number of sockets-2, so letting newmax=2 prevents
297: persistent sockets.
2.1 frystyk 298: <PRE>
2.17 frystyk 299: extern BOOL HTNet_setMaxSocket (int newmax);
300: extern int HTNet_maxSocket (void);
2.1 frystyk 301: </PRE>
2.36 eric 302: <H3>
2.43 frystyk 303: Socket Counters
304: </H3>
305: <PRE>
306: extern void HTNet_increaseSocket (void);
307: extern void HTNet_decreaseSocket (void);
308:
309: extern int HTNet_availableSockets (void);
310: </PRE>
311: <H3>
312: Persistent Socket Counters
313: </H3>
314: <PRE>
315: extern void HTNet_increasePersistentSocket (void);
316: extern void HTNet_decreasePersistentSocket (void);
317:
318: extern int HTNet_availablePersistentSockets (void);
319: </PRE>
320: <H3>
321: Any Ongoing Connections?
322: </H3>
323: <P>
324: Returns whether there are active requests. Idle persistent sockets do not
325: count as active.
326: <PRE>
327: extern BOOL HTNet_isIdle (void);
328: </PRE>
329: <H3>
2.36 eric 330: List Active Queue
331: </H3>
332: <P>
333: Returns the list of active requests that are currently having an open connection.
334: Returns list of HTNet objects or NULL if error.
2.1 frystyk 335: <PRE>
2.17 frystyk 336: extern HTList *HTNet_activeQueue (void);
2.22 frystyk 337: extern BOOL HTNet_idle (void);
2.29 frystyk 338: </PRE>
2.36 eric 339: <H3>
340: Are we Active?
341: </H3>
342: <P>
343: We have some small functions that tell whether there are registered requests
344: in the Net manager. There are tree queues: The <EM>active</EM>, the
345: <EM>pending</EM>, and the <EM>persistent</EM>. The <EM>active</EM> queue
346: is the set of requests that are actively sending or receiving data. The
347: <EM>pending</EM> is the requests that we have registered but which are waiting
348: for a free socket. The <EM>Persistent</EM> queue are requets that are waiting
349: to use the same socket in order to save network resoures (if the server
350: understands persistent connections).
351: <H4>
352: Active Reqeusts?
353: </H4>
354: <P>
2.29 frystyk 355: Returns whether there are requests in the <EM>active</EM> queue or not
356: <PRE>
357: extern BOOL HTNet_idle (void);
358: </PRE>
2.36 eric 359: <H4>
360: Registered Requests?
361: </H4>
362: <P>
363: Returns whether there are requests registered in any of the lists or not
2.29 frystyk 364: <PRE>
365: extern BOOL HTNet_isEmpty (void);
2.1 frystyk 366: </PRE>
2.36 eric 367: <H3>
368: List Pending Queue
369: </H3>
370: <P>
371: Returns the list of pending requests that are waiting to become active. Returns
372: list of HTNet objects or NULL if error
2.1 frystyk 373: <PRE>
2.17 frystyk 374: extern HTList *HTNet_pendingQueue (void);
2.1 frystyk 375: </PRE>
2.36 eric 376: <H2>
2.37 frystyk 377: Creation and Deletion Methods
2.36 eric 378: </H2>
379: <P>
2.37 frystyk 380: The Net object is intended to live as long as the request is still active.
381: In that regard it is very similar to the <A HREF="HTReq.html">Request Object
382: </A>. However, the main difference is that a Net object represents a "thread"
383: in the Library and a request may have multiple "threads" - an example is
384: a FTP request which has a thread to handle the control connection and one
385: to handle the data connections.
386: <H3>
387: Create a new Object
388: </H3>
389: <P>
390: If we have more than HTMaxActive connections already then put this into the
391: pending queue, else start the request by calling the call back function
392: registered with this access method. Returns YES if OK, else NO
2.27 frystyk 393: <PRE>
2.28 frystyk 394: extern BOOL HTNet_newClient (HTRequest * request);
2.27 frystyk 395: </PRE>
2.36 eric 396: <P>
397: You can create a new HTNet object as a new request to be handled. If we have
398: more than HTMaxActive connections already then return NO. Returns YES if
399: OK, else NO
2.17 frystyk 400: <PRE>
2.39 frystyk 401: extern BOOL HTNet_newServer (HTRequest * request, HTNet * net, char *access);
2.26 frystyk 402: </PRE>
2.36 eric 403: <P>
2.27 frystyk 404: And you can create a plain new HTNet object using the following method:
2.26 frystyk 405: <PRE>
2.39 frystyk 406: extern HTNet * HTNet_new (SOCKET sockfd, HTRequest * request);
2.20 frystyk 407: </PRE>
2.36 eric 408: <H3>
2.37 frystyk 409: Duplicate an existing Object
2.36 eric 410: </H3>
411: <P>
412: Creates a new HTNet object as a duplicate of the same request. Returns YES
413: if OK, else NO.
2.20 frystyk 414: <PRE>
2.30 frystyk 415: extern HTNet * HTNet_dup (HTNet * src);
2.17 frystyk 416: </PRE>
2.37 frystyk 417: <H3>
2.43 frystyk 418: Launch a Net Object
419: </H3>
420: <P>
421: Start a Net obejct by calling the protocol module.
422: <PRE>extern BOOL HTNet_start (HTNet * net);
423: </PRE>
424: <H3>
2.37 frystyk 425: Delete an Object
426: </H3>
427: <P>
428: Deletes the HTNet object from the list of active requests and calls any
429: registered call back functions IF not the status is HT_IGNORE. This is used
430: if we have internal requests that the app doesn't know about. We also see
431: if we have pending requests that can be started up now when we have a socket
2.43 frystyk 432: free. The filters are called in the reverse order of which they were registered
433: (last one first);
2.37 frystyk 434: <PRE>
435: extern BOOL HTNet_delete (HTNet * me, int status);
436: </PRE>
437: <H3>
438: Delete ALL HTNet Objects
439: </H3>
440: <P>
441: Deletes all HTNet object that might either be active or pending We DO NOT
442: call the call back functions - A crude way of saying goodbye!
443: <PRE>
444: extern BOOL HTNet_deleteAll (void);
445: </PRE>
2.36 eric 446: <H2>
2.38 frystyk 447: Net Class Methods
2.36 eric 448: </H2>
449: <H3>
450: Make an Object Wait
451: </H3>
452: <P>
453: Let a net object wait for a persistent socket. It will be launched from the
454: HTNet_delete() function when the socket gets free.
2.19 frystyk 455: <PRE>
456: extern BOOL HTNet_wait (HTNet *net);
457: </PRE>
2.36 eric 458: <H3>
459: Priority Management
460: </H3>
461: <P>
462: Each HTNet object is created with a priority which it inherits from the
463: <A HREF="HTReq.html">Request manager</A>. However, in some stuations it is
464: useful to be to change the current priority after the request has been started.
465: These two functions allow you to do this. The effect will show up the first
466: time (which might be imidiately) the socket blocks and control returns to
467: the event loop. Also have a look at how you can do this before the request
468: is issued in the <A HREF="HTReq.html">request manager</A>.
2.23 frystyk 469: <PRE>
470: extern HTPriority HTNet_priority (HTNet * net);
471: extern BOOL HTNet_setPriority (HTNet * net, HTPriority priority);
472: </PRE>
2.36 eric 473: <H3>
474: Persistent Connections
475: </H3>
476: <P>
477: You can set a Net object to handle persistent connections for example using
478: HTTP, NNTP, or FTP. You can control whether a Net object supports persistent
479: connections or not using this function.
2.33 frystyk 480: <PRE>
481: extern BOOL HTNet_persistent (HTNet * net);
482: </PRE>
2.36 eric 483: <P>
484: You can set or disable a Net object supporting persistent connections using
485: this function:
2.33 frystyk 486: <PRE>
2.43 frystyk 487: extern BOOL HTNet_setPersistent (HTNet * net,
488: BOOL persistent,
489: HTTransportMode mode);
2.33 frystyk 490: </PRE>
2.36 eric 491: <H3>
492: Kill a Request
493: </H3>
494: <P>
495: Kill the request by calling the call back function with a request for closing
496: the connection. Does not remove the object. This is done by HTNet_delete()
497: function which is called by the load routine. Returns OK if success, NO on
498: error
2.1 frystyk 499: <PRE>
2.17 frystyk 500: extern BOOL HTNet_kill (HTNet * me);
2.1 frystyk 501: </PRE>
2.36 eric 502: <H3>
503: Kill ALL requests
504: </H3>
505: <P>
506: Kills all registered (active+pending) requests by calling the call back function
507: with a request for closing the connection. We do not remove the HTNet object
508: as it is done by HTNet_delete(). Returns OK if success, NO on error
2.1 frystyk 509: <PRE>
2.17 frystyk 510: extern BOOL HTNet_killAll (void);
2.28 frystyk 511: </PRE>
2.36 eric 512: <H3>
513: Create Input and Output Streams
514: </H3>
515: <P>
516: You create the input stream and bind it to the channel using the following
517: methods. Please read the description in the
518: <A HREF="HTIOStream.html">HTIOStream module</A> on the parameters
519: <EM>target</EM>, <EM>param</EM>, and <EM>mode</EM>. Both methods return YES
520: if OK, else NO.
2.34 frystyk 521: <PRE>
2.44.2.1! eric 522: #if 0
2.34 frystyk 523: extern HTInputStream * HTNet_getInput (HTNet * net, HTStream * target,
524: void * param, int mode);
2.44.2.1! eric 525: #endif
! 526: extern HTOutputStream * HTNet_getOutput (HTNet * me, void * param, int mode);
2.34 frystyk 527: </PRE>
2.37 frystyk 528: <H3>
529: Net Context Descriptor
530: </H3>
2.36 eric 531: <P>
2.37 frystyk 532: Just like the <A HREF="../../../../WWW/Library/src/HTReq.html#context">request
533: object</A>, a net object can be assigned a context which keeps track of context
534: dependent information. The Library does not use this information nor does
535: it depend on it but it allows the application to customize a net object to
536: specific uses.
537: <PRE>extern BOOL HTNet_setContext (HTNet * net, void * context);
538: extern void * HTNet_context (HTNet * net);
539: </PRE>
2.36 eric 540: <H3>
541: Socket Descriptor
542: </H3>
2.28 frystyk 543: <PRE>
544: extern BOOL HTNet_setSocket (HTNet * net, SOCKET sockfd);
545: extern SOCKET HTNet_socket (HTNet * net);
2.17 frystyk 546: </PRE>
2.36 eric 547: <H3>
2.39 frystyk 548: The Request Object
549: </H3>
550: <P>
2.43 frystyk 551: The <A HREF="HTReq.html">Request object</A> is normally set up automatically
552: but can be changed at a later time.
2.39 frystyk 553: <PRE>
554: extern BOOL HTNet_setRequest (HTNet * net, HTRequest * request);
555: extern HTRequest * HTNet_request (HTNet * net);
556: </PRE>
557: <H3>
2.36 eric 558: The Transport Object
559: </H3>
560: <P>
2.34 frystyk 561: The <A HREF="HTTransport.html">transport object</A> is normally set up
562: automatically but can be changed at a later time.
2.17 frystyk 563: <PRE>
2.34 frystyk 564: extern BOOL HTNet_setTransport (HTNet * net, HTTransport * tp);
565: extern HTTransport * HTNet_transport (HTNet * net);
566: </PRE>
2.36 eric 567: <H3>
568: The Channel Object
569: </H3>
2.34 frystyk 570: <PRE>
571: extern BOOL HTNet_setChannel (HTNet * net, HTChannel * channel);
572: extern HTChannel * HTNet_channel (HTNet * net);
573: </PRE>
2.36 eric 574: <H3>
575: The Host Object
576: </H3>
2.34 frystyk 577: <PRE>
578: extern BOOL HTNet_setHost (HTNet * net, HTHost * host);
579: extern HTHost * HTNet_host (HTNet * net);
580: </PRE>
2.36 eric 581: <H3>
582: The DNS Object
583: </H3>
2.43 frystyk 584: <P>
585: The DNS object keeps track of the DNS entries that we have already checked
586: out.
2.34 frystyk 587: <PRE>
588: extern BOOL HTNet_setDns (HTNet * net, HTdns * dns);
589: extern HTdns * HTNet_dns (HTNet * net);
590: </PRE>
2.43 frystyk 591: <P>
592: If we are talking to a multi-homed host then we may connect to any of the
593: homes. In that case we store the current home in the Net object so that we
594: can query about it later.
2.41 frystyk 595: <PRE>
596: extern int HTNet_home (HTNet * net);
2.44.2.1! eric 597: extern HTStream * HTNet_getReadStream(HTNet * net);
2.41 frystyk 598: </PRE>
2.34 frystyk 599: <PRE>
2.17 frystyk 600: #endif /* HTNET_H */
2.1 frystyk 601: </PRE>
2.36 eric 602: <P>
603: <HR>
2.34 frystyk 604: <ADDRESS>
2.44.2.1! eric 605: @(#) $Id: HTNet.html,v 2.44 1996/10/07 02:05:03 frystyk Exp $
2.34 frystyk 606: </ADDRESS>
2.36 eric 607: </BODY></HTML>
Webmaster