|
Packit |
8f70b4 |
/*
|
|
Packit |
8f70b4 |
* lftp - file transfer program
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* Copyright (c) 1996-2012 by Alexander V. Lukyanov (lav@yars.free.net)
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
8f70b4 |
* it under the terms of the GNU General Public License as published by
|
|
Packit |
8f70b4 |
* the Free Software Foundation; either version 3 of the License, or
|
|
Packit |
8f70b4 |
* (at your option) any later version.
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
8f70b4 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
8f70b4 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
8f70b4 |
* GNU General Public License for more details.
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
8f70b4 |
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
8f70b4 |
*/
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#ifndef RESOLVER_H
|
|
Packit |
8f70b4 |
#define RESOLVER_H
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#include "ProcWait.h"
|
|
Packit |
8f70b4 |
#include "buffer.h"
|
|
Packit |
8f70b4 |
#include "xarray.h"
|
|
Packit |
8f70b4 |
#include "Cache.h"
|
|
Packit |
8f70b4 |
#include "network.h"
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
class Resolver : public SMTask, protected ProtoLog
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
xstring hostname;
|
|
Packit |
8f70b4 |
xstring portname;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
xstring service;
|
|
Packit |
8f70b4 |
xstring proto;
|
|
Packit |
8f70b4 |
xstring defport;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int port_number;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int pipe_to_child[2];
|
|
Packit |
8f70b4 |
SMTaskRef<ProcWait> w;
|
|
Packit |
8f70b4 |
SMTaskRef<IOBuffer> buf;
|
|
Packit |
8f70b4 |
Timer timeout_timer;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
xarray<sockaddr_u> addr;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void AddAddress(int family,const char *a,int len,unsigned int scope);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
xstring err_msg;
|
|
Packit |
8f70b4 |
bool done;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void MakeErrMsg(const char *f);
|
|
Packit |
8f70b4 |
void DoGethostbyname();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
static int FindAddressFamily(const char *name);
|
|
Packit |
8f70b4 |
static void ParseOrder(const char *s,int *o);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void LookupOne(const char *name);
|
|
Packit |
8f70b4 |
void LookupSRV_RR();
|
|
Packit |
8f70b4 |
const char *error;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
static class ResolverCache *cache;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool no_cache;
|
|
Packit |
8f70b4 |
bool use_fork;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
int Do();
|
|
Packit |
8f70b4 |
bool Done() { return done; }
|
|
Packit |
8f70b4 |
bool Error() { return err_msg!=0; }
|
|
Packit |
8f70b4 |
const char *ErrorMsg() { return err_msg; }
|
|
Packit |
8f70b4 |
const xarray<sockaddr_u>& Result() { return addr; }
|
|
Packit |
8f70b4 |
size_t GetResultSize() { return addr.count()*addr.get_element_size(); }
|
|
Packit |
8f70b4 |
int GetResultNum() { return addr.count(); }
|
|
Packit |
8f70b4 |
void GetResult(void *m) { memcpy(m,addr.get(),GetResultSize()); }
|
|
Packit |
8f70b4 |
void UseCache(bool y) { no_cache=!y; }
|
|
Packit |
8f70b4 |
void NoCache() { UseCache(false); }
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
Resolver(const char *h,const char *p,const char *defp=0,const char *ser=0,
|
|
Packit |
8f70b4 |
const char *pr=0);
|
|
Packit |
8f70b4 |
~Resolver();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void Reconfig(const char *name=0);
|
|
Packit |
8f70b4 |
const char *GetLogContext() { return hostname; }
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
class ResolverCacheEntryLoc
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
xstring_c hostname;
|
|
Packit |
8f70b4 |
xstring_c portname;
|
|
Packit |
8f70b4 |
xstring_c defport;
|
|
Packit |
8f70b4 |
xstring_c service;
|
|
Packit |
8f70b4 |
xstring_c proto;
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
ResolverCacheEntryLoc(const char *h,const char *p,const char *defp,const char *ser,const char *pr)
|
|
Packit |
8f70b4 |
: hostname(h), portname(p), defport(defp), service(ser), proto(pr) {}
|
|
Packit |
8f70b4 |
const char *GetClosure() const { return hostname; }
|
|
Packit |
8f70b4 |
bool Matches(const char *h,const char *p,const char *defp,const char *ser,const char *pr);
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class ResolverCacheEntryData
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
xarray<sockaddr_u> addr;
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
ResolverCacheEntryData(const sockaddr_u *a,int n) {
|
|
Packit |
8f70b4 |
addr.nset(a,n);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
void SetData(const sockaddr_u *a,int n) {
|
|
Packit |
8f70b4 |
addr.nset(a,n);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
void GetData(const sockaddr_u **a,int *n) {
|
|
Packit |
8f70b4 |
*n=addr.count();
|
|
Packit |
8f70b4 |
*a=addr.get();
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class ResolverCacheEntry : public CacheEntry, public ResolverCacheEntryLoc, public ResolverCacheEntryData
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
ResolverCacheEntry(const char *h,const char *p,const char *defp,const char *ser,const char *pr,
|
|
Packit |
8f70b4 |
const sockaddr_u *a,int n) : ResolverCacheEntryLoc(h,p,defp,ser,pr), ResolverCacheEntryData(a,n) {
|
|
Packit |
8f70b4 |
SetResource("dns:cache-expire",GetClosure());
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class ResolverCache : public Cache, public ResClient
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
ResolverCacheEntry *Find(const char *h,const char *p,const char *defp,const char *ser,const char *pr);
|
|
Packit |
8f70b4 |
ResolverCacheEntry *IterateFirst() { return (ResolverCacheEntry*)Cache::IterateFirst(); }
|
|
Packit |
8f70b4 |
ResolverCacheEntry *IterateNext() { return (ResolverCacheEntry*)Cache::IterateNext(); }
|
|
Packit |
8f70b4 |
ResolverCacheEntry *IterateDelete(){ return (ResolverCacheEntry*)Cache::IterateDelete(); }
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
void Add(const char *h,const char *p,const char *defp,
|
|
Packit |
8f70b4 |
const char *ser,const char *pr,const sockaddr_u *a,int n);
|
|
Packit |
8f70b4 |
void Find(const char *h,const char *p,const char *defp,
|
|
Packit |
8f70b4 |
const char *ser,const char *pr,const sockaddr_u **a,int *n);
|
|
Packit |
8f70b4 |
ResolverCache();
|
|
Packit |
8f70b4 |
void Reconfig(const char *);
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#endif // RESOLVER_H
|