4
12
2011
8

Google 字典大降级

2011年4月13日更新:

今天Google字典又回来了。而且我确认过了,昨天不是4月1日。Google这是技术故障?

2011年8月8日更新:

今天,Google 字典再一次消失了。。。


今天打开火狐时惊讶地发现,我一直打开着的“Google字典”标签被一个搜索“字典”的Google搜索页替换了。又看到书签工具栏上少了几项,我以为这也是火狐的bug,重启之,书签工具栏正常了,但还是没有Google字典。使用“关键字搜索”打开一个新网页,看到 URL 从https://www.google.com/dictionary跳转走,才知道坏了。

是的,Google 字典已经降级为Google搜索了!cnbeta也有报道。Google搜索有查字典的功能这我是早就知道了的,但是我觉得并不好用。不过查一个不认识的词嘛,有必要开个标签进行一次完整的搜索么?Google字典我之前也不用,因为“清除之前的输入(这会覆盖选择区的内容)-> Ctrl-V 或者如果没Ctrl-C过就回到原网页选中单词再回来中键粘贴 -> 点击搜索或者按回车键”这个流程太麻烦了,这通常需要2次键鼠切换、4次按键、1次鼠标点击。而使用关键字搜索每次都得打前缀,然后中键粘贴,然后按回车,鼠标键盘切换好几次也很是不方便,所以我一直使用的是Dict.CN或者是后来因为Dict.CN速度变得太慢而改用的沪江词典的划词小书签,虽然每次用的时候还得点个书签,然后等待会儿,但还是比较方便的。

后来看到这个Super Google Dictionary 2 GreaseMonkey脚本,经过自己的修改,让查词便捷了很多:选中要查的词 -> 转到Google字典标签 -> 在输入框点击左键清除之前的输入 -> 点击中键粘贴要查的词,稍等片刻,结果就出来了。总共三次鼠标点击

一直觉得这样是除了写(或者装)火狐插件之外可能的最快捷的查在线词典的办法了,可是今天,Google字典降级,Google 在 Chrome 浏览器之后再一次用行动证明他们某些设计的脑残。(关于 Chrome 浏览器的脑残之处我有时间整理好了再写。)

Category: 网络 | Tags: google 词典
12
15
2010
4

从UDP到解决DNS污染的脚本

最近做网络课的实验,涉及UDP协议。因为UDP协议比TCP用得少,所以我以前没试过创建几个UDP的socket。现在忽然有了兴致,就试了试。

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

socket创建好了,往哪里发消息呢?我想到了DNS。首先要有报文。没找到容易上手的Python库,就Google到了这个,DNS报文的格式。没功夫细细研究,先弄个报文测试下:

q = b'>:\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x07twitter\x03com\x00\x00\x01\x00\x01'
s.sendto(q, ('8.8.8.8', 53))

\x07twitter\x03com\x00就是要查询的域名了,我想测试什么,明白人都看得出来了。接下来接收回答,接收了多次:

>>> '.'.join(str(int(i)) for i in s.recv(4096)[-4:])
'46.82.174.68'
>>> '.'.join(str(int(i)) for i in s.recv(4096)[-4:])
'128.121.146.100'

再接收的话就阻塞了。对于普通域名,当然是最多只会接收到一次的啦。如果报文出错的话(比如我不小心少写了最后的\x00\x01),是收不到回答的。

有人依据此现象写了个pydnsproxy 放在Google Code上。主页说“暂不公布方法”,但其实很简单。下面是我整理过的代码,转成了Python3的语法:

#!/usr/bin/env python3
# vim:fileencoding=utf-8

from socketserver import *
from socket import *
import sys, os

'''
来源 http://code.google.com/p/pydnsproxy/
'''

DEF_LOCAL_HOST = '127.0.0.1'
DEF_REMOTE_SERVER = '8.8.8.8'
DEF_PORT = 5350
DEF_CONF_FILE = 'dnsserver.conf'
DEF_TIMEOUT = 0.4

gl_remote_server = None

class LocalDNSHandler(BaseRequestHandler):
  def setup(self):
    global gl_remote_server
    if not gl_remote_server:
      remote_server = DEF_REMOTE_SERVER
    else:
      remote_server = gl_remote_server
    self.dnsserver = (remote_server, 53)

  def handle(self):
    data, socket = self.request
    rspdata = self._getResponse(data)
    socket.sendto(rspdata, self.client_address)

  def _getResponse(self, data):
    "Send client's DNS request (data) to remote DNS server, and return its response."
    sock = socket(AF_INET, SOCK_DGRAM) # socket for the remote DNS server
    sock.sendto(data, self.dnsserver)
    sock.settimeout(5)
    while True:
      try:
        rspdata = sock.recv(4096)
        break
      except error as e:
        if e.errno != 11:
          raise
        else:
          print("Try again")
    # "delicious food" for GFW:
    while True:
      sock.settimeout(DEF_TIMEOUT)
      try:
        rspdata = sock.recv(4096)
        print("GFWed?")
      except timeout:
        break
      except error as e:
        if e.errno != 11:
          raise
        else:
          print("Trying again")
    return rspdata

class LocalDNSServer(ThreadingUDPServer):
  pass

def main():
  global gl_remote_server
  try:
    if hasattr(sys, 'frozen'):
      dir = os.path.dirname(sys.executable)
    else:
      dir = os.path.dirname(__file__)
    confFile = os.path.join(dir, DEF_CONF_FILE)
    f = open(confFile, 'r')
    dns = f.read().split('=')
    f.close()
    if len(dns) == 2:
      if dns[0].strip().lower() == 'dns':
        gl_remote_server = dns[1].strip()
      else:
        pass
  except:
    pass
  dnsserver = LocalDNSServer((DEF_LOCAL_HOST, DEF_PORT), LocalDNSHandler)
  dnsserver.serve_forever()

if __name__ == '__main__':
  main()

注意到和原程序不同的是,我捕获了错误号为11的socket.error异常。这个是EAGAIN,“资源临时不可用”,只会在设置了超时后出现。man文档recv(2)对此的解释是:

EAGAIN or EWOULDBLOCK
       The socket is marked  nonblocking  and  the  receive  operation
       would  block, or a receive timeout had been set and the timeout
       expired before data was received.  POSIX.1-2001  allows  either
       error  to be returned for this case, and does not require these
       constants to have the same value,  so  a  portable  application
       should check for both possibilities.

不知道是怎么回事,再次接收却又可以收到数据。也许正如其名,是期待调用者再次尝试吧。我越来越觉得,Python 的异常处理里应该有tryagain这样的语句了。

2012年11月10日更新:更好地摆脱 DNS 污染,请参考此文

Category: 网络 | Tags: DNS python 网络 UDP
11
21
2010
0

Your Google Account

Gmail 钓鱼邮件

今收到的一个失败的钓鱼邮件。

PS:为什么Gmail没有提示此邮件可能存在欺诈什么的呢?

Category: 网络 | Tags: 安全 google

Mastodon | Theme: Aeros 2.0 by TheBuckmaker.com