Задача:
Ограничить входящий(в последствии и исходящий) траффик на машине, так чтобы пользователь, сидящий за ней кроме как по скорости немог определить ограничение. При этом в силу конфигурации сети (ADSL-Ethernet модем — Switch — машины(одна из которых — рассматриваемая)), не получится поставить прокси или что-то подобное.
Из того что сделал:
Я пошел путём хукования
(от слово-то какое). Перехватываю функцию recv. На данный момент тренируюсь на отдельном приложении (Download Master если кому-то интересно). Действительно, скорость ограничевается (пока как константа до 5К бит/сек), но при этом загрузка ЦП возрастает с 0.5% до 70-75%, что недопустимо (так как можно понять, что ограничение стоит). Попытка перехватить select никчему не привела (ИМХО DM её не вызывает).
Внимание, вопрос: Что я делаю не так
Или, покажите/дайте ссылку на работающий пример. Не обязательно Delphi, но желательно (не хочу потом переводить на другой язык).
Спасибо за внимание.
Если нужны исходники того, что уже сделал — скажите — выложу.
Здравствуйте, Danchik, Вы писали:
D>А как вы организовали задержку? Каким макаром? Имеется в виду что в вашем коде приостанавливает трафик.
Довольно просто... в dll была константа (5000 байт/сек) и как только вызывался recv — подсчитвыалось сколько надо отдать программе, урезалась длинна буффера, передаваемая в настоящую recv. Если надо — кусок кода:
function TrueRecv(s: TSocket; var Buf; len, flags: Integer): Integer;
begin
WriteProcessMemory(CurrProc,AdrRecv,@OldRcv,SizeOf(OldCode),Writen);
Result:=Recv(s,Buf,len,flags);
WriteProcessMemory(CurrProc,AdrRecv,@JmpRecv,SizeOf(far_jmp),Writen);
end;
function NewRecv(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
var
buflen:integer;
first:boolean;
i:integer;
Tick:Cardinal;
begin
buflen=Floor((GetTickCount-LastTime)/1000*DownloadSpeed);
if buflen>len then buflen:=len;
Result:=TrueRecv(s,Buf,buflen,flags);
end;